Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
ShoulderDaemon
Oct 9, 2003
support goon fund
Taco Defender

Scaevolus posted:

That's not how aes_encrypt works, though. It expects to get a (random) 128-bit string.

It should probably be noted in the documentation, but I don't see how this is a horror.

It should raise an error if it's handed a key that's too long or too short, rather than use poor key compression. The problem is that by allowing long keys, it encourages misuse (such as inputting an English passphrase) and compounds that problem by using a key compression technique which may significantly reduce entropy in highly structural keys (such as, for example, an English passphrase).

If you're going to do key compression, there's essentially no case where the algorithm MySQL uses is the right choice. The coding horror is that it tries, in a completely braindead and unsafe manner, to correct for a programmer error instead of just failing.

Adbot
ADBOT LOVES YOU

Dessert Rose
May 17, 2004

awoken in control of a lucid deep dream...

ShoulderDaemon posted:

If you're going to do key compression, there's essentially no case where the algorithm MySQL uses is the right choice. The coding horror is that it tries, in a completely braindead and unsafe manner, to correct for a programmer error instead of just failing.

Basically, "helpful" code has absolutely no place anywhere near crypto. Crypto should be the most unforgiving thing you ever deal with in software. And that's because it is, in fact, the most unforgiving thing in software.

McGlockenshire
Dec 16, 2005

GOLLOCKS!

Scaevolus posted:

That's not how aes_encrypt works, though. It expects to get a (random) 128-bit string.

It should probably be noted in the documentation, but I don't see how this is a horror.

The thing is that AES is a freaking standard defined by NIST. You don't take liberties with encryption, and you most certainly don't take liberties with standards.

Unless the wacky things that MySQL's implementation is doing comply with the standard, they're doing it wrong and have created an AES that suddenly isn't the same thing as everyone else's AES.

McGlockenshire
Dec 16, 2005

GOLLOCKS!
Sorry for the back to back posting, but this is a demonstration of the utter broken-ness:
php:
<?php
// We already know that the password gets xored into nothingness, so
// we'll encrypt using the password, then decrypt using the empty string.
    $broken $db->query_one("SELECT AES_ENCRYPT('hello', 'arbitrarypasswrdarbitrarypasswrd')");
    $result mcrypt_decrypt(MCRYPT_RIJNDAEL_128''$brokenMCRYPT_MODE_ECB);
    echo urlencode($result);
// => "hello%0B%0B%0B%0B%0B%0B%0B%0B%0B%0B%0B"
// 0x0b is chr 11, the vertical tab.  This is the padding that their manual warns about.
    echo base64_encode($broken);
// => mDTtUYy8j76a88bst164wA==
// This is the thing we'll expect to see when we've replicated the broken implementation.
// Let's try encrypting the same string using the same key and the same encryption mode (ECB, which is also considered scary/bad now).
    $crypted mcrypt_encrypt(MCRYPT_RIJNDAEL_128'arbitrarypasswrdarbitrarypasswrd''hello'MCRYPT_MODE_ECB);
    echo base64_encode($crypted);
// => 6NfWHAVuIFL9pwFbmNuDEw==
// Well that's not right.
// Let's add the padding.
    $wrong mcrypt_encrypt(MCRYPT_RIJNDAEL_128'arbitrarypasswrdarbitrarypasswrd'urldecode('hello%0B%0B%0B%0B%0B%0B%0B%0B%0B%0B%0B'), MCRYPT_MODE_ECB);
    echo base64_encode($wrong);
// => +sU43m6oTdmX+oPg2bU88g==
// Nope, way different.  Let's blank the key.
    $fuckmysql mcrypt_encrypt(MCRYPT_RIJNDAEL_128''urldecode('hello%0B%0B%0B%0B%0B%0B%0B%0B%0B%0B%0B'), MCRYPT_MODE_ECB);
    echo base64_encode($fuckmysql);
// => mDTtUYy8j76a88bst164wA==
// There, we managed to replicate how broken MySQL is.

Even without the horror of possibly destroying or misinterpreting the encryption key, the data padding means that MySQL's AES is not the same thing as everyone else's AES. That's a coding horror if there ever was one.

e: According to this closed-as-not-a-bug, the padding character is actually the number of characters padded, as recommended in the documentation for PKCS#7 amongst other things. This, of course, despite the fact that not everyone else does it that way. That scares the crap out of me.

e2: I was curious about what mcrypt does when it's given a key that's too long.
php:
<?php
    $key 'a somewhat long passphrase that does not intentionally munch crap';
    $crypted mcrypt_encrypt(MCRYPT_RIJNDAEL_128$keyurldecode('hello%0B%0B%0B%0B%0B%0B%0B%0B%0B%0B%0B'), MCRYPT_MODE_ECB);
// mcrypt_encrypt(): Size of key is too large for this algorithm in php shell code on line 1
    echo base64_encode($crypted)
// => tAM4mX6g69XWmODZ71b00w==
// MySQL gives the following for the same passphrase and un-padded string of 'hello':
// => Y2e2bJXEDf+5qsgb+I4Y8w==

So, PHP does something, but at least warns you about it.

MySQL does a wrong thing and doesn't complain at all. Not even a warning.

e3: Last edit, I promise. If done correctly, PHP will even warn you about maximum lengths. The behavior seems to be truncation of over-long keys, but that isn't actually indicated by the error message.
code:
php > $mc = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_ECB, '');
php > echo $mc;
Resource id #1
php > var_export( mcrypt_enc_get_supported_key_sizes($mc) );
array (
  0 => 16,
  1 => 24,
  2 => 32,
)
php > var_export( mcrypt_enc_get_key_size($mc) );
32
php > $random_shit = openssl_random_pseudo_bytes(32);
php > mcrypt_generic_init($mc, $random_shit, str_repeat("\0", 16)); // It wants an IV, even though ECB doesn't use one
php > echo base64_encode(mcrypt_generic($mc, 'hello'));
eN+lZyoWWMcj+YndwQn7gw==
php > $random_shit .= '1';
php > mcrypt_generic_init($mc, $random_shit, str_repeat("\0", 16));
PHP Warning:  mcrypt_generic_init(): Key size too large; supplied length: 33, max: 32 in php shell code on line 1
php > echo base64_encode(mcrypt_generic($mc, 'hello'));
eN+lZyoWWMcj+YndwQn7gw==
php > 

McGlockenshire fucked around with this message at 01:27 on Feb 25, 2011

spiritual bypass
Feb 19, 2008

Grimey Drawer
Oracle can't kill MySQL soon enough.

Kelson
Jan 23, 2005

ShoulderDaemon posted:

The only thing that's special about about the key that Aleksei Vasiliev chose is that it consists of a 16-character string, repeated an even number of times. Any such key will be equivalent to the all-zeroes key or the empty key.

Nowhere within any of the MySQL code or its support libraries will you find "4re35na2aTaVasAy". It's not a value that comes from the code. It's just a value that Aleksei Vasiliev picked to demonstrate the problem.
That's what I misunderstood; I thought it was a bug in the empty-key code path, not a bug in key reduction. Yep, that is terrible... particularly because one increases the predictability of bytes when xoring ascii together a known number of times.

Scaramouche
Mar 26, 2001

SPACE FACE! SPACE FACE!

rt4 posted:

Oracle can't kill MySQL soon enough.

Is there another OSS solution out there that's actually good? I've always worked in MS/Oracle for everything I've done since the 90s, but I'm curious now if I ever actually have to develop something low cost/personal after my MSDN/OTN expires what I would use.

Janitor Prime
Jan 22, 2004

PC LOAD LETTER

What da fuck does that mean

Fun Shoe
Postgres is great, but you'll find that you have to unlearn a lot of MySQL specific syntax that you thought was standard.

RoadCrewWorker
Nov 19, 2007

camels aren't so great

MEAT TREAT posted:

Postgres is great, but you'll find that you have to unlearn a lot of MySQL specific syntax that you thought was standard.
God yes, i've been relying on primary-key + insert ignore SO much for quick data entry, and every single workaround on postgresql takes ages compared to it. :smith:
Edit: scratch the question, wrong thread. I guess you can count the above as coding horror.

RoadCrewWorker fucked around with this message at 20:14 on Feb 25, 2011

McGlockenshire
Dec 16, 2005

GOLLOCKS!
I dunno, the convenience of INSERT / UPDATE ... RETURNING makes up for the lack of REPLACE / INSERT INTO ... ON DUPLICATE KEY UPDATE and friends. Different things, I know, but it's immensely useful to just return the pkey right from the insert rather than having to poke at the sequence. 9.1 includes the groundwork for making a real upsert a reality.

Then there's also working CHECK clauses, nifty data types (like inet and cidr, which can hold and process both IPv4 and IPv6 addresses and networks), straightforward stored procedures, and other goodies. Related to the most recent horror, the pgcrypto contrib module also happens to include 128-bit AES, and even lets you pick the padding and block modes.

spiritual bypass
Feb 19, 2008

Grimey Drawer

Scaramouche posted:

Is there another OSS solution out there that's actually good? I've always worked in MS/Oracle for everything I've done since the 90s, but I'm curious now if I ever actually have to develop something low cost/personal after my MSDN/OTN expires what I would use.

Because you're already accustomed to Oracle, you'll feel right at home in Postgres. They seem to shoot for Oracle compatibility.

Malloc Voidstar
May 7, 2007

Fuck the cowboys. Unf. Fuck em hard.
code:
private static void vehicle(String arg) {
	String vehicle;
	vehicle =  ( ( arg == "B" ) ? "bus" : 
		     ( arg == "A" ) ? "airplane" : 
		     ( arg == "T" ) ? "train" : 
		     ( arg == "C" ) ? "car" : 
		     ( arg == "H" ) ? "horse" : 
		     "feet" );
	System.out.println(vehicle);
}
vehicle("T");
train


php:
<?
$arg = 'T';
$vehicle = ( ( $arg == 'B' ) ? 'bus' :
             ( $arg == 'A' ) ? 'airplane' :
             ( $arg == 'T' ) ? 'train' :
             ( $arg == 'C' ) ? 'car' :
             ( $arg == 'H' ) ? 'horse' :
             'feet' );
echo $vehicle;
?>
horse


:buddy:

Edison was a dick
Apr 3, 2010

direct current :roboluv: only

Aleksei Vasiliev posted:

horse
:buddy:
:psyboom:
Ok, I'd heard that php was abominable but this is just bizarre.
How does that even happen?

RoadCrewWorker
Nov 19, 2007

camels aren't so great

Edison was a dick posted:

:psyboom:
Ok, I'd heard that php was abominable but this is just bizarre.
How does that even happen?

php:
<?
$arg = 1;
$one = (( $arg == 1 ) ? 'one' :(( $arg == 2 ) ? 'two' : 'nothing')); //'one'
$two =  ( $arg == 1 ) ? 'one' : ( $arg == 2 ) ? 'two' : 'nothing' ;  //'two'
?>
Ahahaha holy poo poo

robostac
Sep 23, 2009
http://php.net/manual/en/language.operators.comparison.php

It appears it somehow ends up evaluating everything before the last ? as one statement, leaving the following:
code:
$vehicle = 'train' ? 'horse' : 'feet'
I love the fact they know it makes no sense so actually recommend you don't use it.

quote:

It is recommended that you avoid "stacking" ternary expressions. PHP's behaviour when using more than one ternary operator within a single statement is non-obvious:

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe
I don't see what's wrong with that. Isn't it just an operator precedence issue? In many situations it is necessary to use brackets to enforce the desired order of operations. This seems no different.

nielsm
Jun 1, 2009



Hammerite posted:

I don't see what's wrong with that. Isn't it just an operator precedence issue? In many situations it is necessary to use brackets to enforce the desired order of operations. This seems no different.

The issue is that the precedence is illogical and different from every other language that has the ternary operator.
The design makes the more common case hard.

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe

nielsm posted:

The issue is that the precedence is illogical and different from every other language that has the ternary operator.

I'd like to be able to disagree, but I looked over Alexei's example and couldn't deduce the rules it uses to evaluate that expression to "horse". Still, if I were at all unsure about the precedence, I'd just slap a few pairs of brackets in so as to make it clear what should happen, so I don't really see the problem.

_aaron
Jul 24, 2007
The underscore is silent.

Hammerite posted:

I'd like to be able to disagree, but I looked over Alexei's example and couldn't deduce the rules it uses to evaluate that expression to "horse". Still, if I were at all unsure about the precedence, I'd just slap a few pairs of brackets in so as to make it clear what should happen, so I don't really see the problem.
PHP was not the first programming language created. Many other languages use a ternary operator with the same order of precedence. Why should PHP come along and change things?

deedee megadoodoo
Sep 28, 2000
Two roads diverged in a wood, and I, I took the one to Flavortown, and that has made all the difference.


_aaron posted:

PHP was not the first programming language created. Many other languages use a ternary operator with the same order of precedence. Why should PHP come along and change things?

PHP is an elaborate troll.

spiritual bypass
Feb 19, 2008

Grimey Drawer
Anyone who's using nested ternaries deserves what he gets.

NotShadowStar
Sep 20, 2000

rt4 posted:

Anyone who's using nested ternaries deserves what he gets.

I agree, it should just be a switch/case, but the logic should at least be consistent.

Janitor Prime
Jan 22, 2004

PC LOAD LETTER

What da fuck does that mean

Fun Shoe

rt4 posted:

Anyone who's using nested ternaries deserves what he gets.

Yes, this is the real horror. PHP is always a horror, so nothing new.

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe

_aaron posted:

PHP was not the first programming language created. Many other languages use a ternary operator with the same order of precedence. Why should PHP come along and change things?

Why shouldn't it? (In general, not in this specific situation.)

Thermopyle
Jul 1, 2003

...the stupid are cocksure while the intelligent are full of doubt. —Bertrand Russell

Hammerite posted:

Why shouldn't it? (In general, not in this specific situation.)

For the reason it's being talked about here. Bucking convention just confuses people. Confusing people is sometimes a painful step needed to implement change for the better, but change for changes sake isn't "for the better".

MononcQc
May 29, 2007

If the behavior is well-documented, convention is only a preconception the programmer brings to the table to get himself confused. :smugdog:

Thermopyle
Jul 1, 2003

...the stupid are cocksure while the intelligent are full of doubt. —Bertrand Russell

MononcQc posted:

If the behavior is well-documented, convention is only a preconception the programmer brings to the table to get himself confused. :smugdog:

Very true. You still end up with lots of confused programmers, though.

tef
May 30, 2004

-> some l-system crap ->

Hammerite posted:

Why shouldn't it? (In general, not in this specific situation.)

principle of least surprise is a good design principle.

i.e 'do what the user expects', and in this case the user might be someone who has used javascript, or any c influenced programming language.


however, this would really only apply if the rest of php wasn't so weird

today I learned 0 == "\n" in php

tef
May 30, 2004

-> some l-system crap ->

HatfulOfHollow posted:

PHP is an elaborate troll.

"PHP is a minor evil perpetrated and created by incompetent amateurs, whereas Perl is a great and insidious evil, perpetrated by skilled but perverted professionals." — Jon Ribbens.

HappyHippo
Nov 19, 2003
Do you have an Air Miles Card?

tef posted:

principle of least surprise is a good design principle.

i.e 'do what the user expects', and in this case the user might be someone who has used javascript, or any c influenced programming language.


however, this would really only apply if the rest of php wasn't so weird

today I learned 0 == "\n" in php

http://php.net/manual/en/types.comparisons.php

Remember:
"php" == 0,
"" == 0,
but "" != "php"

Transitivity does not hold with ==.

Edit: Before someone points it out, yes I know why this happens.

HappyHippo fucked around with this message at 21:06 on Mar 3, 2011

spiritual bypass
Feb 19, 2008

Grimey Drawer
Yes I'll remem:psyboom:

qntm
Jun 17, 2009
That's why you can simply use === and !== in every situation. It's a universal rule that always ensures that two things being compared are exactly identical.

Oops, unless they're objects, in which case you have to use ==. Got me again, PHP!

wwb
Aug 17, 2004

Can we just start a dedicated PHP horrors thread?

dis astranagant
Dec 14, 2006

wwb posted:

Can we just start a dedicated PHP horrors thread?

Pretty sure the thread dedicated to PHP counts, whether they know it or not.

raminasi
Jan 25, 2005

a last drink with no ice
What's wrong with ternary chaining?

bobthecheese
Jun 7, 2006
Although I've never met Martha Stewart, I'll probably never birth her child.

wwb posted:

Can we just start a dedicated PHP horrors thread?

Any horrors thread is bound to contain php.

Any php thread is bound to contain horrors.

There's already one of both.

Making a dedicated PHP Horrors thread would be redundant.

Malloc Voidstar
May 7, 2007

Fuck the cowboys. Unf. Fuck em hard.

GrumpyDoctor posted:

What's wrong with ternary chaining?
It's commonly abused.

but it is useful if the language you are working in doesn't support if-else or switch

# Create spatially interpolated bob-clips
dbob = clp.bob(0,0.5)
edi  = (EdiMode=="NNEDI2") ? defined(edeint) ? (border) ? edeint.pointresize(width(o),height(o)+8, 0,-4,-0,height(o)+8.001 ) : edeint : clp.nnedi2(field=-2)
 \   : (EdiMode=="EEDI2")  ? clp.SeparateFields().EEDI2(field=-2, maxd=EEDI2maxd) 
 \   : (EdiMode=="Yadif")  ? clp.Yadif(mode=1)
 \                        : dbob

NotShadowStar
Sep 20, 2000

GrumpyDoctor posted:

What's wrong with ternary chaining?

It's a huge mess to read and almost assuredly means that you're doing logic that's far too convoluted than it should be. Perhaps if you're doing embedded low level programming where every clock cycle and instruction counts then a huge chain of if/then is probably what you want to do, but doing such low level code readability is very low in your list of priorities anyway.

== is a horror in Javascript as well since the type coercions break transitivity and associativity just as well; but Javascript has generally converged to using === instead. Good loving luck trying to convince the terrible PHP programmers that == is really dangerous. Often when you're working with someone else's PHP code you need to use ==.

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe

bobthecheese posted:

Any horrors thread is bound to contain php.

Any php thread is bound to contain horrors.

There's already one of both.

Making a dedicated PHP Horrors thread would be redundant.

PHP's many and varied shortcomings have been well-documented here and elsewhere. So it seems surprising to me that nobody has either (i) forked it and radically overhauled it (by breaking backwards compatibility); or (ii) set out to write a "better" version which has a less broken parser, more elegantly implemented language features, a more consistent standard library etc. Is there are reason why there isn't a "php, but better" out there?

I mean I know that there are other web scripting languages/frameworks out there, like perl and python and .net. But whenever I've looked into python it's seemed less focused on web development than PHP and all of the material I've looked at about using it for a web application waffles on about whether you're using CGI or Fast-CGI or mod_python or god knows what else, then tells you you've got to choose all kinds of components for your web application because python isn't enough on its own, etc etc... (I'm talking primarily about this guide, which presents a whole lot of discussion about various things but nowhere answers the question of why it has to be so complicated when compared to PHP's implementation.)

And I don't know much about perl but it sounds similar to python but apparently also has bizarre syntax that leads to impenetrable code.

So given that PHP does at least do one or two things right (you can write a script, upload it and it will work right loving now without needing to faff about - and it gets out of your way quite well if you want to do something simple, and has everything you might want in its standard library); but does a lot of things wrong, why isn't there something that takes the good things about PHP and loses the bad parts?

:spergin:

Adbot
ADBOT LOVES YOU

bobthecheese
Jun 7, 2006
Although I've never met Martha Stewart, I'll probably never birth her child.

Hammerite posted:

So given that PHP does at least do one or two things right (you can write a script, upload it and it will work right loving now without needing to faff about - and it gets out of your way quite well if you want to do something simple, and has everything you might want in its standard library); but does a lot of things wrong, why isn't there something that takes the good things about PHP and loses the bad parts?

:spergin:

That's what PHP 6 is meant to do, I think. Problem is that it's pretty much never going to get finished. For the large number of 'php developers' in the world, there are actually very few people developing php, which means that it takes time for features to get added/changed/updated.

While it's fun to rag on PHP for being poo poo, it's still a damned popular language, and actually quite powerful (when it's not being abuse by idiots). Most of the problems with php are, as you said, pretty much centred on people not reading the available documentation (which is really some of the best language documentation I've ever come across).

Doesn't mean it's not fun to pay out on it, though.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply