`end` could have a value of `-1` if a user makes a typo in their expression. You can probably avoid that by checking that `value` also contains `}` _after_ `${`, before entering the body of the loop.

Alternatively, if you've got a fix to `Util.replaceMacro()` pending review, you could copy-paste its implementation here with a TODO to start using the fixed version as soon as it is released.