Obviously, the only way to test whether a string is a valid regular expression is by compiling it (which is done when you call any of the matching functions), so what you're doing makes a lot of sense.
The null-byte protection you have added is actually not necessary since 5.4, because there are already checks made in the leader, the middle and the ending. The latter in particular is a relatively recent commit (2011) to fix this bug.
Setting a lower backtrack and recursion limit is a good enough sandbox, perhaps you could check for a maximum length as well.
That said, this particular solution doesn't provide the ability to use modifiers such as /s
, /i
and /m
; perhaps that's not your main concern at the moment, but rather food for thought :)