Uploaded image for project: 'Minecraft: Java Edition'
  1. Minecraft: Java Edition
  2. MC-201885

Divide by zero error in the Ender dragon entity class can cause a server crash and infinite velocity

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Resolved
    • Resolution: Fixed
    • Affects Version/s: 1.16.3, 1.16.4 Pre-release 1
    • Fix Version/s: 1.16.4 Pre-release 2
    • Labels:
      None
    • Confirmation Status:
      Community Consensus
    • Category:
      Crash
    • Mojang Priority:
      Very Important

      Description

      The bug

      Summoning any living entity on the wings of the ender dragon (same position as the middle of the wing) will give the entity infinite velocity and crash the server. This is due to a divide by zero case with the wings and a living entity.

      How to reproduce

      1. Create a new world
      2. Go to the end
      3. Give yourself a command block and set it to repeat
      4. Enter this command in the command block and power the block:
        /tp @e[type=minecraft:ender_dragon] 0.0 70.0 0.0
        
      5. Summon armor stands on the dragon:
        /execute at @e[type=minecraft:ender_dragon] run summon minecraft:armor_stand
        

        The server crashing after a minute or two

      Code analysis

      Using 1.16.3 yarn mappings.

      We will be looking at the EnderDragonEntity code today.

      Let’s go to:

      public void tickMovement()
      

      Inside this function there is the launchLivingEntities function. Let’s explore this.

      if (!this.world.isClient && this.hurtTime == 0) {
      
      this.launchLivingEntities(this.world.getOtherEntities(this, this.partWingRight.getBoundingBox().expand(4.0, 2.0, 4.0).offset(0.0, -2.0, 0.0), EntityPredicates.EXCEPT_CREATIVE_OR_SPECTATOR));
      
      this.launchLivingEntities(this.world.getOtherEntities(this, this.partWingLeft.getBoundingBox().expand(4.0, 2.0, 4.0).offset(0.0, -2.0, 0.0), EntityPredicates.EXCEPT_CREATIVE_OR_SPECTATOR));
      //removed code
      }
      

      This function takes in the entities around the dragon wing (will later be limited to Living Entities )

      private void launchLivingEntities(List<Entity> entities) {
      
          double d = (this.partBody.getBoundingBox().minX + this.partBody.getBoundingBox().maxX) / 2.0;
          double e = (this.partBody.getBoundingBox().minZ + this.partBody.getBoundingBox().maxZ) / 2.0;
          for (Entity lv : entities) {
              if (!(lv instanceof LivingEntity)) continue;
              double f = lv.getX() - d;
              double g = lv.getZ() - e;
              double h = f * f + g * g;
              lv.addVelocity(f / h * 4.0, 0.2f, g / h * 4.0);
      
      //removed stuff below
          }
      }
      

      From this function call, it takes the wing and finds the middle of it. For the next part, let's say we have an entity at the same location as the middle of the wing and it is a living entity. As the x and z are the same, f and g will be zero. As f and g are zero, h will be zero. Now, as h is zero, the lv.addVelocity will make the x and z velocity infinite as in java a float divide by zero will make a value infinity.

        Attachments

          Activity

            People

            Assignee:
            slicedlime [Mojang] slicedlime
            Reporter:
            Kman032317 Kyle Weber
            Votes:
            16 Vote for this issue
            Watchers:
            7 Start watching this issue

              Dates

              Created:
              Updated:
              Resolved:
              CHK: