Claimed to be an "old hack"

C

Charles Polisher

Quoth (e-mail address removed):
{(!($^O=~/^[M]*$32/i)&&($0=~s!^.*/!!))||($0=~s!.*\\!!)}

What the heck does this do?

I almost certainly doesn't do what it's supposed to do :). That '*$32'
ought to read '.*32$'. Making that correction, we have an expression of
the form

(A && B) || C

which is a nasty shorthand for

if (A) {
B
}
else {
C
}

so expanding that and adding some more whitespace gives

if (! ($^O =~ /^[M].*32$/i) ) {
$0 =~ s!^.*/!!;
}
else {
$0 =~ s!.*\\!!;
}

The only standard value for $^O which matches that pattern is 'MSWin32',
so this is attempting (incorrectly) to remove any directory portion from
$0. It's incorrect because / and \ are not the only possible directory
separators, and Win32 is not the only OS which uses \. Replace it with

use File::Basename qw/basename/;

$0 = basename $0;

which is both correct and comprehensible.

Ben

Thank you so much!
 
I

Ilya Zakharevich

Quoth (e-mail address removed):
{(!($^O=~/^[M]*$32/i)&&($0=~s!^.*/!!))||($0=~s!.*\\!!)}
I almost certainly doesn't do what it's supposed to do :). That '*$32'
ought to read '.*32$'.

Just make sure that $32 eq '.*32$'. ;-) But `$1 means \1'-fix (if
whereever was one - do not remember offhand) may intervene...
Making that correction, we have an expression of
the form

(A && B) || C

which is a nasty shorthand for

if (A) {
B
}
else {
C
}

No, it is not.

Hope this helps,
Ilya
 
R

Randal L. Schwartz

Ben> I know it's not *equivalent*. But, in this case, that *is* how it's
Ben> being used. It's a very usual way of doing a compact if-then-else in
Ben> shell, which is probably where it comes from.

No, it's a broken cargo-culted way of doing a compact if-then-else.

Please don't repeat it.
 
I

Ilya Zakharevich

{(!($^O=~/^[M]*$32/i)&&($0=~s!^.*/!!))||($0=~s!.*\\!!)}
Making that correction, we have an expression of
the form

(A && B) || C

which is a nasty shorthand for

if (A) {
B
}
else {
C
}

No, it is not.

I know it's not *equivalent*. But, in this case, that *is* how it's
being used.

Unclear. It looks like you wanted it mean something like "B never
fails", so C cannot be executed if A succeeds (which is not true), and
you "nasty" is just for "using ||/&& for control flow" (which I also
won't agree with).

From other messages in this thread I conclude that your "nasty
equivalent" might have meant:

"Apparently, the author [wrongly] thought that this expression is an
equivalent".
It's a very usual way of doing a compact if-then-else in
shell, which is probably where it comes from.

Again, is s/way/wrong way/ assumed here? I do (A&&(B||true))||C sometimes...

Still puzzled,
Ilya
 
W

Willem

Ben Morrow wrote:
)
) Quoth Ilya Zakharevich <[email protected]>:
)> >
)> > Quoth (e-mail address removed):
)> >> {(!($^O=~/^[M]*$32/i)&&($0=~s!^.*/!!))||($0=~s!.*\\!!)}
)>
)> > I almost certainly doesn't do what it's supposed to do :). That '*$32'
)> > ought to read '.*32$'.
)>
)> Just make sure that $32 eq '.*32$'. ;-) But `$1 means \1'-fix (if
)> whereever was one - do not remember offhand) may intervene...
)>
)> > Making that correction, we have an expression of
)> > the form
)> >
)> > (A && B) || C
)> >
)> > which is a nasty shorthand for
)> >
)> > if (A) {
)> > B
)> > }
)> > else {
)> > C
)> > }
)>
)> No, it is not.
)
) I know it's not *equivalent*. But, in this case, that *is* how it's
) being used. It's a very usual way of doing a compact if-then-else in
) shell, which is probably where it comes from.

Still, not true.

It's roughly equivalent to:
if (A) {
if (!B) {
C
}
} else {
C
}

You see, if the first substitution fails (does nothing), the second will
then still be executed.

Which is probably not what was intended, but still.


SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT
 
C

C.DeRykus

Ben> I know it's not *equivalent*. But, in this case, that *is* how it's
Ben> being used. It's a very usual way of doing a compact if-then-else in
Ben> shell, which is probably where it comes from.

No, it's a broken cargo-culted way of doing a compact if-then-else.

There appear to be more serious things afoot too.
The exploit script didn't have warnings turned on
which hides the 'uninitialized' message from $32.
There's a missing '.' after the [M] too (which Ben
added)since any OS string would match:

'$^O =~ /^[M]*$32/i'.

So, for clarity, Deparse refactors the corrected
regex:

{(!($^O=~/^[M].*32$/i)&&($0=~s!^.*/!!))||($0=~s!.*\\!!)}

into:

$0 =~ s/.*\\// unless not $^O =~ /^[M].32$/i
and $0 =~ s[^.*/][];


which is much easier to understand and easier
on the eyes...but still the wrong solution for
the reasons mentioned and should be replaced
with File::basename.
 
I

Ilya Zakharevich

No, no value judgements were implied either way.

I did not mean "value judgement" here. I meant semantic: your
"equivalence" holds only if B always succeeds if A succeeds.

Ilya
 
T

Ted Zlatanov

....
IZ> I did not mean "value judgement" here. I meant semantic: your
IZ> "equivalence" holds only if B always succeeds if A succeeds.

I think this is one of the areas where Lisp's prefix notation is
significantly clearer than any of the alternatives, e.g.

(setq result (or (and A B) C))

I wish Perl had a simple way to construct boolean logic in prefix
notation. A plain function would not work, of course.

Ted
 
D

David Canzi

Quoth Ilya Zakharevich said:
{(!($^O=~/^[M]*$32/i)&&($0=~s!^.*/!!))||($0=~s!.*\\!!)}
Making that correction, we have an expression of
the form

(A && B) || C

which is a nasty shorthand for

if (A) {
B
}
else {
C
}

No, it is not.

I know it's not *equivalent*. But, in this case, that *is* how it's
being used.

Unclear. It looks like you wanted it mean something like "B never
fails", so C cannot be executed if A succeeds (which is not true), and
you "nasty" is just for "using ||/&& for control flow" (which I also
won't agree with).

I don't have a big problem with using || and && for control flow. I
think it's a little ugly, but not importantly so.

I've been thinking lately about what happens when somebody else
reads my code and learns from it.

I spent a lot of time in the last couple of years untying code
knots created by a co-worker. I saw one particularly offensive
piece of code and recognized it as something he probably learned
from reading my code.

When people see code like "A && B || C" being used as if it's
equivalent to the if-else construct you wrote above, they're
too likely to think it's really neat, and not likely enough to
notice that it's dependent on B always being true. And they'll
go on to write incorrect code using this trick. And somebody
else will have to spend time debugging it.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,901
Latest member
Noble71S45

Latest Threads

Top