FiguraMC / Figura

Extensively customize your character with Figura!
https://modrinth.com/mod/figura
GNU Lesser General Public License v2.1
225 stars 44 forks source link

add host.regexMatch(string, regular expression) #210

Closed TheBunnyMan123 closed 4 months ago

TheBunnyMan123 commented 4 months ago

This adds a client.regexMatch function to figura.

Example for capturing a link:

if (client.regexMatch(input, "^(https?|ftp|file)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]") then
    log("Link!")
else
    log("Not a link!")
end
Avatcher commented 4 months ago

There's already string.find(str, regex) in regular Lua. What's the point of this PR?

GrandpaScout commented 4 months ago

There's already string.find(str, regex) in regular Lua. What's the point of this PR?

Regular Lua does not use regex for its matches. It uses Lua Patterns.

PoolloverNathan commented 4 months ago

inb4 /a+(b|(c|d+)+)+e/. Try matching that against e.g. "adddddddddddddddddddddddddddddddddddddddddddf" and your game will likely freeze for a while or crash. Do we have any way to prevent this?

Edit: Nearly guaranteed to crash your game:

repeat until client.regexMatch("a" .. ("d"):rep(1000) .. "f", "a+(b|(c|+)+)+e")
PoolloverNathan commented 4 months ago

Also, while you're at it, is there a way to expose the regex's group ((...)) matches when it successfully matches?

TheBunnyMan123 commented 4 months ago

What do you mean by exist the group if it matches?

Also, I can place a maximum time of, say, 10 seconds before forcing it to stop.

PoolloverNathan commented 4 months ago

What do you mean by exist the group if it matches?

JS's RegExp.exec returns an array* of the capture group contents so you can refer to subparts of the matched pattern. I don't know if Java has something similar, but if it does it'd probably be useful to expose.

Also, I can place a maximum time of, say, 10 seconds before forcing it to stop.

Yeah, but in a loop that's iirc 3 instructions to freeze the game for 10 seconds each. Combined with the relatively high number of instructions in TICK and RENDER, this lets you lower other people's FPS to near-mine incredibly easily.

TheBunnyMan123 commented 4 months ago

Yeah, I'm going to see if I can think of a way to stop that. One thing I could do is cache the results, so if you input a duplicate string and expression it will just return the same value, but that wouldn't prevent randomness. I could also put a cap on the max string sizes.

TheBunnyMan123 commented 4 months ago

I could also track if it is run more than, say, 5 times a second and error out the avatar running it

Oh but pcall. I could also disable new calculations for 1 minute and give a toast saying what is happening

Avatcher commented 4 months ago

JS's RegExp.exec returns an array* of the capture group contents so you can refer to subparts of the matched pattern. I don't know if Java has something similar, but if it does it'd probably be useful to expose.

There are Matcher#group(int), Matcher#groupCount() and a lot more methods that help to get match subparts in Java, so it is completely possible to expose these to Lua, what I agree would be useful.

TooManyLimits commented 4 months ago

One potential way to limit the time taken is to implement regex in Lua, then instructions will be counted while processing the regex. You can make it come with all avatars, kind of like how Figura already defines new things in the math library.

PoolloverNathan commented 4 months ago

One potential way to limit the time taken is to implement regex in Lua, then instructions will be counted while processing the regex. You can make it come with all avatars, kind of like how Figura already defines new things in the math library.

Potentially it could instead be implemented in Java for performance, using Avatar::punish to make matching still cost instructions? I don't know if mixins work in system libraries, but if they do I will certainly be happy to abuse them for this.

TheBunnyMan123 commented 4 months ago

That is a great idea, I just gotta figure out a good scale Factor

TheBunnyMan123 commented 4 months ago

I'm not going to work on this further. Too much work for something that helps very little. Closing.

TheBunnyMan123 commented 4 months ago

Actually I'm gonna make it host only I don't want to manually parse links. That also fixes the issue of crashing other players

TheBunnyMan123 commented 4 months ago

It is host only now. I can still add an avatar:punish if needed

TheBunnyMan123 commented 4 months ago

also I checked and can't find a way to give what matched. best we can do is have the user compare regexFind and regexReplace unless yall know something I dont

TheBunnyMan123 commented 4 months ago

this doesn't fit with figura. closing