LuckPerms

LuckPerms

41.4k Downloads

Client crash when using group settrack

lucassevelin opened this issue · 9 comments

commented

Description

When using the command /lp group parent settrack the game (client, not server) crashes. I have tried with several different groups and the problem still exits, I'm using YMAL for the persmission files.

Reproduction steps

Run the command described above, and use tab for atleast the group. When press tab on the prefferd group, the game crashes.

Expected behaviour

I'm expecting the command to not crash when it's ran.

Environment details

  • Server type/version: Spigot running version '1.16.4-R0.1-SNAPSHOT'
  • LuckPerms version: v5.2.44

Any other relevant details

Here is the crash-report minecraft generates:

---- Minecraft Crash Report ----
// My bad.

Time: 2020-12-29 14:25
Description: Rendering screen

java.lang.StringIndexOutOfBoundsException: String index out of range: -5
at java.lang.String.substring(String.java:1955)
at dlm.a(SourceFile:315)
at dlm.a(SourceFile:280)
at dlm$$Lambda$3726/164157410.apply(Unknown Source)
at dlq.b(SourceFile:423)
at dlh.a(SourceFile:86)
at dnq.a(SourceFile:201)
at dzz.a(SourceFile:616)
at djz.e(SourceFile:1048)
at djz.e(SourceFile:681)
at net.minecraft.client.main.Main.main(SourceFile:215)

A detailed walkthrough of the error, its code path and all known details is as follows:

-- Head --
Thread: Render thread
Stacktrace:
at java.lang.String.substring(String.java:1955)
at dlm.a(SourceFile:315)
at dlm.a(SourceFile:280)
at dlm$$Lambda$3726/164157410.apply(Unknown Source)
at dlq.b(SourceFile:423)
at dlh.a(SourceFile:86)
at dnq.a(SourceFile:201)

-- Screen render details --
Details:
Screen name: dnq
Mouse location: Scaled: (480, 254). Absolute: (960.000000, 508.000000)
Screen size: Scaled: (960, 509). Absolute: (1920, 1017). Scale factor of 2.000000

-- Affected level --
Details:
All players: 1 total; [dzm['SwedishMonkey'/18698478, l='ClientLevel', x=-2924.27, y=67.00, z=3181.70]]
Chunk stats: Client Chunk Cache: 729, 483
Level dimension: minecraft:overworld
Level spawn location: World: (-2918,82,3134), Chunk: (at 10,5,14 in -183,195; contains blocks -2928,0,3120 to -2913,255,3135), Region: (-6,6; contains chunks -192,192 to -161,223, blocks -3072,0,3072 to -2561,255,3583)
Level time: 267680349 game time, 273903885 day time
Server brand: Spigot
Server type: Non-integrated multiplayer server
Stacktrace:
at dwt.a(SourceFile:449)
at djz.c(SourceFile:2239)
at djz.e(SourceFile:699)
at net.minecraft.client.main.Main.main(SourceFile:215)

-- System Details --
Details:
Minecraft Version: 1.16.4
Minecraft Version ID: 1.16.4
Operating System: Windows 10 (amd64) version 10.0
Java Version: 1.8.0_51, Oracle Corporation
Java VM Version: Java HotSpot(TM) 64-Bit Server VM (mixed mode), Oracle Corporation
Memory: 1043968352 bytes (995 MB) / 2113929216 bytes (2016 MB) up to 2147483648 bytes (2048 MB)
CPUs: 8
JVM Flags: 9 total; -XX:HeapDumpPath=MojangTricksIntelDriversForPerformance_javaw.exe_minecraft.exe.heapdump -Xss1M -Xmx2G -XX:+UnlockExperimentalVMOptions -XX:+UseG1GC -XX:G1NewSizePercent=20 -XX:G1ReservePercent=20 -XX:MaxGCPauseMillis=50 -XX:G1HeapRegionSize=32M
Launched Version: 1.16.4
Backend library: LWJGL version 3.2.2 build 10
Backend API: GeForce GTX 1050/PCIe/SSE2 GL version 4.6.0 NVIDIA 452.41, NVIDIA Corporation
GL Caps: Using framebuffer using OpenGL 3.0
Using VBOs: Yes
Is Modded: Probably not. Jar signature remains and client brand is untouched.
Type: Client (map_client.txt)
Graphics mode: fancy
Resource Packs:
Current Language: English (US)
CPU: 8x Intel(R) Core(TM) i7-7700HQ CPU @ 2.80GHz

commented

Do you happen to edit the yaml files directly?

commented

No i'm using the command in game, and the first time i tried the command i created the group in-game so the YAML file was never touched. The second time i tried using a file I have modified the YAML file on but it had the same result.

commented

Can you reproduce this with just LuckPerms on the server?

commented

Yes i get the same error when using a server with only LuckPerms installed. I have also tried to do a fresh install where i removed all LuckPerms files and i still receive the same error.

commented

Can you run export your permission data and upload it here? Also provide the exact command you’re using.

commented

Sure! I did an export on the server with only LuckPerms installed and all settings default. I ran the command /lp export , i hope that is what you meant!

{
"metadata": {
"generatedBy": "SwedishMonkey",
"generatedAt": "2020-12-29 16:05:20 CET"
},
"groups": {
"default": {
"nodes": []
},
"test": {
"nodes": []
}
},
"tracks": {
"mod": {
"groups": []
}
},
"users": {}
}

The game crashes when i try to run /lp group test parent settrack mod default

commented

Interesting. I mean you don’t have any groups in the track. So that looks like an issue. But frankly that shouldn’t crash the client. I believe that is actually a bug.

commented

The important part of the mapped exception is as follows:

java.lang.StringIndexOutOfBoundsException: String index out of range: -5
    at java.lang.String.substring(String.java:1955)
    at net.minecraft.client.gui.components.CommandSuggestions.formatText(SourceFile:315) (Yarn: net.minecraft.client.gui.screen.CommandSuggestor.highlight)
    at net.minecraft.client.gui.components.CommandSuggestions.formatChat(SourceFile:280) (Yarn: net.minecraft.client.gui.screen.CommandSuggestor.provideRenderText)

This leads me to believe LuckPerms sends an invalid Brigadier suggestion of an invalid string (or just whitespace that may be trimmed?) -- I'm not too familiar with Brigadier, but it may be because of an invalid length (if that is sent at all).

The cause for this is the following Yarn-mapped line:

// Context of the line: (net.minecraft.client.gui.screen.CommandSuggestor.highlight, L243 in Yarn-mapped Procyon output of 1.16.4, Yarn branch 1.16.4 commit b2f3e4ecf92129bb7d89083f6634aacd7992b23e)
// private static OrderedText highlight(ParseResults<CommandSource> parse, String original, int firstCharacterIndex) { -- original = input string
// List<OrderedText> list4 = Lists.newArrayList();
// @NonNegative int integer5 = beginIndex
// @NonNegative int integer10 = max = Math.max(parsedArgument.getRange().getStart() - firstCharacterIndex, 0); -- integer10 < original.length()
// integer5 = beginIndex gets assigned the value of @NonNegative int integer11 = min = Math.min(parsedArgument.getRange().getEnd() - firstCharacterIndex, original.length());
// MOJANG_LITERAL_STYLE is an unmapped name in Yarn, and Mojang knows it as `LITERAL_STYLE` (`c` in obf) -- its style indicates this is a literal Brigadier argument

list4.add(OrderedText.styledString(original.substring(integer5, integer10), CommandSuggestor.MOJANG_LITERAL_STYLE));

The user's JVM has the following String#substring(int, int)String definition: https://hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/share/classes/java/lang/String.java#l1945

    public String substring(int beginIndex, int endIndex) {
        if (beginIndex < 0) {
            throw new StringIndexOutOfBoundsException(beginIndex);
        }
        if (endIndex > value.length) {
            throw new StringIndexOutOfBoundsException(endIndex);
        }
        int subLen = endIndex - beginIndex;
        if (subLen < 0) {
            throw new StringIndexOutOfBoundsException(subLen);
        }
        return ((beginIndex == 0) && (endIndex == value.length)) ? this
                : new String(value, beginIndex, subLen);
    }

It is rather likely that only subLen < 0 may be true in this case, because the beginIndex is non-negative in the calling code (substring is never called because min <= 0 -> continue in the calling for-loop), and a negative endIndex requires value.length (value is a char[]) to be negative, which is impossible.

The issue would therefore likely be because max < min, because parsedArgument.getRange().getEnd() - firstCharacterIndex and original.length() would be larger than our max. We already know original.length() must larger by the time we get to this line, as any other case is continued before this -- the firstCharacterIndex (which to me seems to be that of the trimmed input) is therefore not high enough. min = end - firstCharIdx must therefore be larger than max, resulting in max - min < 0.

This would presumably be possible with a faulty Brigadier tree sent to the client, where strings may end with whitespace, or potentially a good ol' client bug.

commented

Interesting bug! Thanks @Proximyst for the detailed analysis, you saved me a lot of time attempting to do the same 😅

The issue seems to be that arguments in the same parse tree need to have unique names - hence the reason why the crash happens with /lp group .... and not /lp user ...

The slimmed down tree looks like this:

luckperms {
  user {
    user brigadier:string single_word {
      parent {
        settrack {
          track brigadier:string single_word {
            group brigadier:string single_word {
              context brigadier:string greedy_phrase;
            }
          }
        }
      }
    }
  }
  group {
    group brigadier:string single_word {
      parent {
        settrack {
          track brigadier:string single_word {
            group brigadier:string single_word {
              context brigadier:string greedy_phrase;
            }
          }
        }
      }
    }
  }
}

By the time you get to tab-completing the context arg in the group tree, there are two arguments group brigadier:string single_word with the same name, but at different positions! Just an oversight on my part that hadn't shown up until now.

Anyway, giving the second group argument a unique name seems to fix the crash!

Thanks again for reporting :)