mIRC Home    About    Download    Register    News    Help

Print Thread
#223007 12/07/10 03:36 AM
Joined: Apr 2010
Posts: 8
T
Nutrimatic drinks dispenser
OP Offline
Nutrimatic drinks dispenser
T
Joined: Apr 2010
Posts: 8
I've just noticed when you do something like
Code:
On *:TEXT:*:#:{
  lol #
}
alias lol { 
  timer 1 1 msg $1 lol
}

Just as an example.
If the channel name is #$me it will actually do
msg $me lol (Without the #)

I know this is because you have the #$1- thing.
But I do believe it shouldn't work for this.
If it does work it should be $chr(35) $+ $me

Joined: Oct 2003
Posts: 3,918
A
Hoopy frood
Offline
Hoopy frood
A
Joined: Oct 2003
Posts: 3,918
This is not a bug. /timer evaluates the command in question when the timer fires. You have to sanitize your data before passing any use input to /timer. If you want it to be $chr(35) $+ $me that's how you should pass it into the timer command.

Code:
alias lol timer 1 1 msg $replace($1,$,$!!) lol


There are other (better) ways to sanitize /timer commands, and there are a few safe_timer command variants out there (check these forums/hawkee/mircscripts.org). Maybe someone will post the snippet here.

There's really nothing else mIRC can do in this situation. There is no way for /timer to know that $1 is a channel name-- not everything starting with # is an irc channel, and even if it did, there's no way to know that the user does not want $1 to be evaluated. It's up to you as the scripter to handle this case.


- argv[0] on EFnet #mIRC
- "Life is a pointer to an integer without a cast"
Joined: Apr 2010
Posts: 8
T
Nutrimatic drinks dispenser
OP Offline
Nutrimatic drinks dispenser
T
Joined: Apr 2010
Posts: 8
The point is in order to do that one would have to change all of there timers. Now what if you wanted something to evaluate?
Either way the way the #$1- is set up

this should be #My-Name
at the least.

You'd also have the problem when you //msg #$Me $me is $r(1,100) $+ % cool.

It wouldn't effect me. This problem came to my attention when a Bot Owner contacted me. But there are ALOT of people who wouldn't know about this error/glitch/feature.

Joined: Feb 2006
Posts: 546
J
Fjord artisan
Offline
Fjord artisan
J
Joined: Feb 2006
Posts: 546
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
Joined: Oct 2003
Posts: 3,918
A
Hoopy frood
Offline
Hoopy frood
A
Joined: Oct 2003
Posts: 3,918
Yes, it's a gotcha, but it's not new; this behaviour has been around since at least 1997. It's unfortunate that people don't know about this issue, and it's equally unfortunate that timers are so error prone regarding evaluation-- but this issue is not a bug, it's behaviour by design.


- argv[0] on EFnet #mIRC
- "Life is a pointer to an integer without a cast"
Joined: Apr 2010
Posts: 8
T
Nutrimatic drinks dispenser
OP Offline
Nutrimatic drinks dispenser
T
Joined: Apr 2010
Posts: 8
Originally Posted By: argv0
Yes, it's a gotcha, but it's not new; this behaviour has been around since at least 1997. It's unfortunate that people don't know about this issue, and it's equally unfortunate that timers are so error prone regarding evaluation-- but this issue is not a bug, it's behaviour by design.


Even if you do
//msg #$ME Hello it will only msg 'TehGrape' not #TehGrape so either way as I said it is a bug.
This is judging by the way #$1- works

Joined: Jun 2009
Posts: 3
K
Self-satisified door
Offline
Self-satisified door
K
Joined: Jun 2009
Posts: 3
Originally Posted By: TehGrape
Code:
On *:TEXT:*:#:{
  lol #
}
alias lol { 
  timer 1 1 msg $1 lol
}

Keep in mind that this code works for 99% of all channel combinations on most networks, and that the script DOESN'T work as expected if it is ran from a channel that starts '#$'

So if I had this loaded on my mIRC, it would work correctly in every channel until I joined say "#$address", and someone tried to use the script.

I agree that the way the timer executes things can cause problems, but this is more to do with the behaviour of "#$alias" which shouldn't be evaluated in this manner if passed in this way. I believe that is only valid syntax because of the "/j /join #$1-" oddity.

I found that $!eval( $chan ,0) worked properly in my tests.

Last edited by KHobbits; 12/07/10 08:35 PM.
Joined: Jan 2003
Posts: 2,523
Q
Hoopy frood
Offline
Hoopy frood
Q
Joined: Jan 2003
Posts: 2,523
Originally Posted By: KHobbits
I found that $!eval( $chan ,0) worked properly in my tests.
Try joining #$me).

The trick jaytea mentioned is about as simple/short as you can get if you want a fully working solution.


/.timerQ 1 0 echo /.timerQ 1 0 $timer(Q).com
Joined: Oct 2003
Posts: 3,918
A
Hoopy frood
Offline
Hoopy frood
A
Joined: Oct 2003
Posts: 3,918
Just because it doesn't do what you want does not make it a bug.

#$me returns $me because #$identifier only works on $N ($1, $2, etc.). For every other identifier, it returns the identifier without #. This may be quirky, but it's the expected behaviour for evaluating #$identifier. And before you question this, #$identifier is meant to evaluate-- this is part of mIRC's existing syntax and is not going to change.

This has nothing to do with the timer issue, however. The timer issue you reported has everything to do with /timer evaluation. It just so happens the code you're evaluating is #$me, but it could easily have been any other special value in mIRC.

Consider:

Code:
on *:TEXT:!echo *:.timer 1 3 msg # $2


In this case $2 is not a channel but the user's input. If a user wrote "!echo $me" it would return "BOTNICK", not "$me".

Again, nothing to do with #$1-, everything to do with the fact that /timer will be evaluating "msg #channel $me" when the timer fires. For this reason you should always sanitize all timer commands that execute non-literal data, especially from the user/server.



- argv[0] on EFnet #mIRC
- "Life is a pointer to an integer without a cast"
Joined: Oct 2003
Posts: 3,918
A
Hoopy frood
Offline
Hoopy frood
A
Joined: Oct 2003
Posts: 3,918
Originally Posted By: KHobbits
I agree that the way the timer executes things can cause problems, but this is more to do with the behaviour of "#$alias" which shouldn't be evaluated in this manner if passed in this way.


I pointed this out before, but to reiterate: #$identifier is always evaluated-- this is part of mIRC's syntax-- it is not a bug, it is not going to change. It has quirky edge cases but it is not a quirk.

Note again (as I just wrote in my previous reply) that this is not only a problem for "#$identifier".. it's also a problem for just having "$identifier" anywhere in user data. The script provided by the OP happened to be targeted to a specific scenario, but the same issue can occur for any user data. If his lol alias did "msg lol $1" instead of "msg $1 lol" and he passed in some dollar amount ($20.00), he would get the same thing. Try it:

Code:
//timer 1 1 echo -a $$?="How much money?"


Enter $20.00 in the box.

You can just as easily enter #$mychannel. They will both evaluate. This shows that the issue is not specific to #$identifier, it is a /timer issue-- and not a bug but a "feature".


- argv[0] on EFnet #mIRC
- "Life is a pointer to an integer without a cast"
Joined: Oct 2004
Posts: 8,330
Hoopy frood
Offline
Hoopy frood
Joined: Oct 2004
Posts: 8,330
Just another example:

Code:
//timer 5 1 echo -a $ticks


It will also evaluate. And, in this case, it will evaluate only once rather than each repetition. It's just how mIRC is designed to function with timers and you have to take that into consideration when using them and use a variety of different methods to get what you want from the timer... such as for this case, using:

Code:
//timer 5 1 echo -a $!ticks


As a side note, it's interesting that rather than this triggering every 1.000 seconds for me, it triggers once every 1.014 seconds every time. Maybe $ticks evaluation takes 14ms to do, but that seems a little high.


Invision Support
#Invision on irc.irchighway.net
Joined: Jul 2006
Posts: 4,145
W
Hoopy frood
Offline
Hoopy frood
W
Joined: Jul 2006
Posts: 4,145
Quote:
As a side note, it's interesting that rather than this triggering every 1.000 seconds for me, it triggers once every 1.014 seconds every time. Maybe $ticks evaluation takes 14ms to do, but that seems a little high.
$ticks evaluation takes 0 ms, $ticks just has an accuracy of 15 ms, and timers are not accurate anyway

Last edited by Wims; 13/07/10 03:15 AM.

#mircscripting @ irc.swiftirc.net == the best mIRC help channel
Joined: Dec 2002
Posts: 344
D
Pan-dimensional mouse
Offline
Pan-dimensional mouse
D
Joined: Dec 2002
Posts: 344
Unfortunately, mIRC's default aliases.ini and popups.ini files make use of the #$ construct, which means removing support for it would cause most people's aliases and popups to break. So even if you could argue that it ought to be removed for security reasons (which I personally would agree with), I don't think it's practical to remove it.

As far as double evaluating timers go, I'd like to see a switch to make the timer not evaluate when triggered (similar to $read "n" switch). I'd be surprised if this has never been suggested though, so perhaps I am overlooking something.

Joined: Aug 2004
Posts: 7,252
R
Hoopy frood
Offline
Hoopy frood
R
Joined: Aug 2004
Posts: 7,252
Quote:
I'd like to see a switch to make the timer not evaluate when triggered
While not as simple as a switch, identifiers and variables can be made to evaluate when the timer executes, rather than when it is triggered, by using the general format of $!<identifier> or %!<variable>

Eg:
Code:
/timer 100 10 msg $!chan This is being sent to $!chan

With this, the identifier $chan is evaluated each time the display needs to go out, rather than once when the timer is triggered.

Joined: Sep 2005
Posts: 2,881
H
Hoopy frood
Offline
Hoopy frood
H
Joined: Sep 2005
Posts: 2,881
%!variable does not work. You should instead use % $+ variable, like this:

Code:
//set %x $!ticks | timer 1 1 echo -a % $+ x

Joined: Feb 2006
Posts: 546
J
Fjord artisan
Offline
Fjord artisan
J
Joined: Feb 2006
Posts: 546
Originally Posted By: drum
As far as double evaluating timers go, I'd like to see a switch to make the timer not evaluate when triggered (similar to $read "n" switch). I'd be surprised if this has never been suggested though, so perhaps I am overlooking something.


great idea, i would like to see this for /timer as well as /scon and /scid. you should post a feature suggestion :P


"The only excuse for making a useless script is that one admires it intensely" - Oscar Wilde
Joined: Sep 2005
Posts: 2,881
H
Hoopy frood
Offline
Hoopy frood
H
Joined: Sep 2005
Posts: 2,881
I'd like to see two methods of controlling evaluation, one for evaluating straight away and not when the timer fires, and one for evaluating when the timer fires and not straight away.

For example:

Code:
; evaluates now - output is "%y" (literal string)
set %y $!me | set %x % $+ y | timertest -i1 1 2 echo -a %x
; evaluates later - outcome is whatever $ticks is at the time the timer fires.
timertest -i2 1 2 echo -a $ticks

Joined: Feb 2006
Posts: 546
J
Fjord artisan
Offline
Fjord artisan
J
Joined: Feb 2006
Posts: 546
i considered that distinction, the first method is of course the most useful. the second method just takes away the fun of thinking about escaping code with $!ident, % $+ var and such! and it's unusual that you would want no code to evaluate initially, to the point where the second method becomes useful :P


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

Link Copied to Clipboard