Client crashfix: load meta after digging (#5801)
authorParamat <paramat@users.noreply.github.com>
Tue, 23 May 2017 17:54:37 +0000 (18:54 +0100)
committerLoïc Blot <nerzhul@users.noreply.github.com>
Tue, 23 May 2017 17:54:37 +0000 (19:54 +0200)
Fixes a crash caused in MTGame by breaking and right-clicking a chest.

If loading meta, digging, node can disappear and we looked at meta, which is wrong because meta became NULL.

Pointer is invalidated and we read wrong memory area

src/game.cpp

index 5d4edb3d01d3ee4b0e54d8c9d85e804a1cccf8bc..1ddf07fd114ea73c5bb5df25a9dd0bd7738797bb 100644 (file)
@@ -3744,6 +3744,13 @@ void Game::handlePointingAtNode(const PointedThing &pointed, const ItemDefinitio
        */
 
        ClientMap &map = client->getEnv().getClientMap();
+
+       if (runData.nodig_delay_timer <= 0.0 && isLeftPressed()
+                       && client->checkPrivilege("interact")) {
+               handleDigging(pointed, nodepos, playeritem_toolcap, dtime);
+       }
+
+       // This should be done after digging handling
        NodeMetadata *meta = map.getNodeMetadata(nodepos);
 
        if (meta) {
@@ -3757,11 +3764,6 @@ void Game::handlePointingAtNode(const PointedThing &pointed, const ItemDefinitio
                }
        }
 
-       if (runData.nodig_delay_timer <= 0.0 && isLeftPressed()
-                       && client->checkPrivilege("interact")) {
-               handleDigging(pointed, nodepos, playeritem_toolcap, dtime);
-       }
-
        if ((getRightClicked() ||
                        runData.repeat_rightclick_timer >= m_repeat_right_click_time) &&
                        client->checkPrivilege("interact")) {
@@ -3977,10 +3979,9 @@ void Game::handleDigging(const PointedThing &pointed, const v3s16 &nodepos,
                bool is_valid_position;
                MapNode wasnode = map.getNodeNoEx(nodepos, &is_valid_position);
                if (is_valid_position) {
-                       if (client->moddingEnabled()) {
-                               if (client->getScript()->on_dignode(nodepos, wasnode)) {
-                                       return;
-                               }
+                       if (client->moddingEnabled() && 
+                                       client->getScript()->on_dignode(nodepos, wasnode)) {
+                               return;
                        }
                        client->removeNode(nodepos);
                }