4

I want to replace some characters in string e.g.

console.log( 
    "truefalse".replace("e","E")
)

but using jsfuck convenction where only 6 chars are allowed: []()!+, here for increase readability also JS strings with letters a-z and A-Z and numbers 0-9 are allowed (because it is easy to convert such strings to 6-char jsf code). So I can write it as follows

console.log(
  "truefalse"["replace"]("e","E")
)

but in above code I use forbidden character - comma: ,. So I use technique of calling function with 2 (and more) paremeters discovered by trincot here as follows

console.log(
  "truefalse"["split"]()["concat"]([["e"]["concat"]("E")])
    ["reduce"](""["replace"]["apply"]["bind"](""["replace"]))
)

Now I want to use regular expression in replace function and write code using above restrictions

console.log(
  "truefalse"["replace"](/e/g,"E")
)

but I don't know what to do with regexp part /e/g ?. It is possible to do it without using any kind of 'eval' (where string is interpreted as code)?

j08691
  • 204,283
  • 31
  • 260
  • 272
Kamil Kiełczewski
  • 85,173
  • 29
  • 368
  • 345
  • `new RegExp('e', 'g')` – Barmar Aug 26 '20 at 20:18
  • @Barmar - but how to run it using 6 chars []()!+ and strings ? Such code `"truefalse"["replace"]("new RegExp('e', 'g')","E")` will not work. This one `"truefalse"["replace"](new RegExp('e', 'g'),"E")` is forbidden (letters can be used only in valid JS strings) – Kamil Kiełczewski Aug 26 '20 at 20:21
  • If you are only looking for regex because of the `g` flag, there is now `replaceAll` where you can pass "e" and it will replace all of them. – trincot Aug 26 '20 at 20:56
  • @trincot regexp is needed because I also want to use following method `.match(/..../g)` (to split characters to 4-char chunks... may be it is not possible – Kamil Kiełczewski Aug 26 '20 at 20:57
  • That you could achieve with `[].constructor.from("abcdefghijkl".matchAll("...."))` because the argument is cast to a regex. You'd need to just chain a `.flat()` to it though. – trincot Aug 26 '20 at 21:04
  • @trincot this string inside matchAll is "parsed" as regexp? If yes then create answer - I will give you at least +1 – Kamil Kiełczewski Aug 26 '20 at 21:08
  • I will not be able to benefit from a +1 today as I maxed out for today ;-) – trincot Aug 26 '20 at 21:27

1 Answers1

2

I don't see a way to get access to the RegExp constructor without evaluating code, like with the Function constructor:

""["replace"]["constructor"]("return RegExp")()

But consider this

  • If you need to replace multiple occurrences, you can use the replaceAll method with a string for first argument
  • The methods match and matchAll can be used with a string argument, and a RegExp object will be created for that string on the fly, as if you had called .match(RegExp(str))

So if for instance you need to split a string in chunks of four characters, you can use .matchAll("...."). There is just two things to do more:

  • As matchAll returns an iterator, you need to make an array from it; like with Array.from.
  • As you don't have direct access to the Array variable, you could use [].constructor instead.
  • The returned chunks are in a nested array, which needs flattening. You could chain a .flat() call for that.

So that becomes

console.log(
  []["constructor"]["from"]("abcdefghijkl"["matchAll"]("...."))["flat"]()
);
trincot
  • 317,000
  • 35
  • 244
  • 286
  • 1
    Thank you for your answer - it is helpful. I thought that It can be problem with it. As addition I say that `"truefalse"["replace"](/e/g,"E")` for simple patterns can be replaced by `"truefalse"["split"]("e")["join"]("E")` – Kamil Kiełczewski Aug 26 '20 at 21:30
  • 1
    Addition2: Your eval like version can be shorted to `[]["fill"]["constructor"]("return this")()["RegExp"]("e","g")` (which produce shorter jsf code) – Kamil Kiełczewski Aug 26 '20 at 21:46
  • Indeed, and you can evaluate `"return RegExp"`. – trincot Aug 27 '20 at 06:58
  • may be this question also will be interesting for you - [here](https://stackoverflow.com/q/63618313/860099) – Kamil Kiełczewski Aug 27 '20 at 14:33
  • thank you for your all answers :) - they helps me a lot with work on this jsf parser which produce very [small-jsfuck](https://github.com/kamil-kielczewski/small-jsfuck) code (old parsers create output houndred/thousands bigger than input - this one create only ~24x greater code + constant ~23kB bootstrap) – Kamil Kiełczewski Sep 01 '20 at 14:41