you're right, this feature of mIRC's timers has long been a source of unexpected behavior and potentially exploitable code. thankfully there always exists a way to dictate exactly how you want the code to perform, even if it is largely unknown to newcomers.

the simplest way to escape a string passed to a timer, to avoid the double evaluations that you noted, is:

Code:
timer 1 1 msg $!decode( $encode($1,m) ,m)


if you have $decode() unlocked in mIRC options and don't expect to be handling strings that would become too long for mIRC to handle when encoded (Mime encoding adds an extra 1/3 to the string's length), this is a simple way of retaining your /timer's commands but adding that vital layer of security that is currently lacking.

other options include using custom safe timer snippets as argv0 mentioned, or, placing potentially dangerous pieces of code in variables and referring to them in the timer (escaping with $eval( ,0) wherever necessary).


"The only excuse for making a useless script is that one admires it intensely" - Oscar Wilde