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

Storing a tag with a mismatched type in a numeric array tag succeeds even though its elements are not changed

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Unresolved
    • None
    • 1.15.2, 20w16a, 20w17a, 20w18a, 20w20b, 1.16 Pre-release 5, 1.16.1, 1.16.2 Pre-release 1, 1.16.2, 1.16.3, 1.16.4 Pre-release 1, 1.16.4, 20w45a, 20w46a, 20w48a, 20w49a, 20w51a, 21w03a, 1.16.5, 21w05b, 21w08b, 21w10a, 21w15a, 21w16a, 21w19a, 1.17 Pre-release 1, 1.17, 1.17.1, 21w37a, 1.18.1, 22w03a, 22w05a, 1.18.2 Pre-release 1, 1.18.2, 22w12a, 1.19.1, 1.19.2, 1.19.3 Release Candidate 1, 1.19.3 Release Candidate 2, 1.19.3, 23w03a, 1.19.4, 23w18a, 1.20.1, 23w31a, 1.20.2, 23w42a, 23w46a
    • Confirmed
    • Commands

      The bug

      Storing a tag with a mismatched type in a numeric array tag (byte/int/long array tag) does not throw an exception even though its elements result in the same as before.

      How to reproduce

      1. /data modify storage mc-178997: array set value [B; 0B]
      2. /data modify storage mc-178997: array[0] set value 0b

        Nothing changed. The specified properties already have these values

      3. /data modify storage mc-178997: array[0] set value 0s

        Modified storage mc-178997:, this should not succeed because

      4. /data get storage mc-178997: array

        Storage mc-178997: has the following contents: [B; 0B], the contents are the same as in step 1.

      Code analysis

      The cause is that the tag to be set (newTag) is compared to the current tag (oldTag) before setTag that performs an implicit conversion. Two tags with different types never be equal, but can be equal after implicit conversion. In this case, setTag should not return 1 (successfully set).

      // net.minecraft.commands.arguments.NbtPathArgument.IndexedElementNode
      
      public int setTag(Tag tag, Supplier<Tag> supplier) {
          if (tag instanceof CollectionTag) {
              CollectionTag<?> collectionTag = (CollectionTag) tag;
              int size = collectionTag.size();
              int index = this.index < 0 ? size + this.index : this.index;
              if (0 <= index && index < size) {
                  Tag oldTag = (Tag) collectionTag.get(index);
                  Tag newTag = (Tag) supplier.get();
                  if (!newTag.equals(oldTag) && collectionTag.setTag(index, newTag)) {
                  //  ^^^^^^^^^^^^^^^^^^^^^^    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                  //  comparison                implicit conversion and set
      
                      return 1;
                  }
              }
          }
          
          return 0;
      }

            Unassigned Unassigned
            intsuc intsuc
            Votes:
            5 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              CHK: