Skip to content

Fix PDO MySQL URI test #8451

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from
Closed

Conversation

mvorisek
Copy link
Contributor

@mvorisek mvorisek commented Apr 28, 2022

"\0" char in URI causes the remaining part completely ignored, thus testing effectively only mysql:dbname=letshopeinvalid

but this URI then tested connection /w default host/port/credentials resulting with a many different failures (for example, consider MySQL server accessible on localhost /w and /wo default port)

@mvorisek mvorisek changed the title Fix PDO URI test Fix PDO Mysql URI test Apr 28, 2022
@mvorisek mvorisek force-pushed the fix_mysql_uri_test branch from ecc9a01 to c6afdf8 Compare April 28, 2022 09:01
@mvorisek mvorisek marked this pull request as ready for review April 28, 2022 09:54
@mvorisek mvorisek changed the title Fix PDO Mysql URI test Fix PDO MySQL URI test Apr 28, 2022
@cmb69
Copy link
Member

cmb69 commented Apr 28, 2022

Isn't that NUL character an important part of the test? Can you show the test failures?

@mvorisek
Copy link
Contributor Author

mvorisek commented Apr 28, 2022

I belive no, @cmb69 please test yourself

the important fact is this tests is not working correctly if the MySQL server is not on localhost/default port

if server port is for example 3307, I get:

SQLSTATE[HY000] [2002] No connection could be made because the target machine actively refused it

with this PR, I get [1049] Unknown database 'letshopeinvalid' correctly

@cmb69
Copy link
Member

cmb69 commented Apr 28, 2022

if server port is for example 3307, I get:

SQLSTATE[HY000] [2002] No connection could be made because the target machine actively 

Why not add that to the list of expected failure messages?

@mvorisek
Copy link
Contributor Author

because the test is wrong, we definitely do not want to touch other service than defined in DSN

@cmb69
Copy link
Member

cmb69 commented Apr 28, 2022

"\0" char in URI causes the remaining part completely ignored

This appears to be the whole point of that part of the test. It is about "mysql:dbname=letshopeinvalid\0$dsn; that "letshopeinvalid" indicates that the rest of the DSN is supposed to be ignored. If we remove the NUL byte, we might as well drop that part of the test altogether.

@mvorisek
Copy link
Contributor Author

"\0" char in URI causes the remaining part completely ignored

This appears to be the whole point of that part of the test. It is about "mysql:dbname=letshopeinvalid\0$dsn; that "letshopeinvalid" indicates that the rest of the DSN is supposed to be ignored. If we remove the NUL byte, we might as well drop that part of the test altogether.

maybe, would it be fine if I add something like chr(0) . ';charset=nonsense'?

test will be fixed and the "\0" behaviour will be kept tested (even if I am not 100% sure if that behaviour is per some spec)

@cmb69
Copy link
Member

cmb69 commented Apr 28, 2022

maybe, would it be fine if I add something like chr(0) . ';charset=nonsense'?

If that would error without the NUL byte, that appears to be reasonable. Maybe @kamil-tekiela has thoughts on this.

even if I am not 100% sure if that behaviour is per some spec

"Spec" might be an exaggeration, but it tests the implementation (which is as it is for whatever reason):

php-src/ext/pdo/pdo.c

Lines 165 to 167 in 0df2886

if (data_source[i] == '\0') {
break;
}

@mvorisek mvorisek force-pushed the fix_mysql_uri_test branch from 6e7abf5 to d708bf7 Compare April 28, 2022 12:57
@kamil-tekiela
Copy link
Member

kamil-tekiela commented Apr 28, 2022

this test was completely wrong

Sorry, I am not seeing how it is wrong.

  • "\0" char in URI causes the remaining part completely ignored

That's the whole idea. The test is checking whether the URI past the NUL byte is ignored. If it's ignored then PDO should error out on the incorrect database name.

  • thus testing effectively only mysql:dbname=letshopeinvalid

It's testing whether the NUL byte ends DSN

but this URI then tested connection /w default host/port/credentials resulting with a many different failures (for example, consider MySQL server accessible on localhost /w and /wo default port)

Ok, that part might need fixing. The DSN should contain the same config except dbname which should be incorrect.

maybe, would it be fine if I add something like chr(0) . ';charset=nonsense'?

And what would that test? We hope that this test never reaches this part so invalid charset is meaningless to this test. Better keep that part as it was.

@mvorisek
Copy link
Contributor Author

Sorry, I am not seeing how it is wrong.

you answered it by yourself:

but this URI then tested connection /w default host/port/credentials resulting with a many different failures (for example, consider MySQL server accessible on localhost /w and /wo default port)

Ok, that part might need fixing. The DSN should contain the same config except dbname which should be incorrect.

now the test is testing the behaviour as before & /w full DSN, can you please review the changes?

@mvorisek
Copy link
Contributor Author

tested with #8392, I can confirm the changes are fixing the test

@@ -73,5 +71,5 @@ MySQLPDOTest::skip();
print "done!";
?>
--EXPECTF--
[003] URI=uri:file://%spdomuri.tst, DSN=mysql%sdbname=%s, File=%spdomuri.tst (%d bytes, 'mysql%sdbname=letshopeinvalid%s'), chr(0) test, EXPECTED ERROR
[003] URI=uri:file://%spdomuri.tst, DSN=mysql:%sdbname=%s, File=%spdomuri.tst (%d bytes, 'mysql:%sdbname=letshopeinvalid%snonsense'), EXPECTED ERROR
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did the output change?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

, chr(0) test is not needed here as the line/echo is "identified" by [003], other additions here are to improve the expectation

@mvorisek
Copy link
Contributor Author

mvorisek commented May 2, 2022

can this PR be merged? I need it for #8392

Comment on lines 41 to 43
fwrite($fp, sprintf('mysql:dbname=letshopeinvalid;%s%s',
chr(0), $dsn));
$dsnUnknownDatabase = preg_replace('~dbname=[^;]+~', 'dbname=letshopeinvalid', $dsn)
. chr(0) . ';host=nonsense;unix_socket=nonsense';
fwrite($fp, $dsnUnknownDatabase);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems to me that this change defeats the purpose of that part of the test. The test is for checking that a NUL byte terminates the DSN string. If there is no NUL byte (or it would be ignored), later options override previous options (dbname=good;dbname=bad would be the same as dbname=bad).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I fixed the test in a minimalistic way.

I aggre, we can basically copy the 1st test with fwrite($fp, $dsn. chr(0) . ';host=nonsense;unix_socket=nonsense');, not bother with dbname=letshopeinvalid and expect the same result. Do you want me to do that?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I aggre, we can basically copy the 1st test with fwrite($fp, $dsn. chr(0) . ';host=nonsense;unix_socket=nonsense');, not bother with dbname=letshopeinvalid and expect the same result.

That make sense to me.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done, 1st test vs chr(0) test:

image

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CI issue unrelated, let's merge this PR, needed for #8392

@cmb69 cmb69 closed this in 136ef6f May 3, 2022
@mvorisek mvorisek deleted the fix_mysql_uri_test branch May 3, 2022 18:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants