Skip to content
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

Fixed OpenGL version string being parsed incorrectly on some platforms #1390

Merged
merged 1 commit into from Apr 5, 2018

Conversation

binary1248
Copy link
Member

Fixes #1249.

Copy link
Member

@LaurentGomila LaurentGomila left a comment

Choose a reason for hiding this comment

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

The string length should be checked in each if, right now you're accessing unchecked elements of the version array, which is UB.

A final else is missing after all the chained ifs, leaving the version number to an undefined state. Maybe we could set it to 1.1 before testing the version, so that we don't have to write else blocks.

@binary1248
Copy link
Member Author

std::strncmp compares two possibly null-terminated character arrays. If the null terminator is encountered in either array before n characters are compared, it ends the comparison. In our case, there is no danger because both parameters are guaranteed to be null-terminated.

@LaurentGomila
Copy link
Member

LaurentGomila commented Mar 18, 2018

I was talking about what happens inside the blocks:

m_settings.majorVersion = version[13] - '0';
m_settings.minorVersion = version[15] - '0';

strlen(version) should be > 15 in this case.

@binary1248
Copy link
Member Author

I guess you don't want to have to assume that the OpenGL implementation is standard compliant? 😁

@LaurentGomila
Copy link
Member

What standard? We are "parsing" strings we know nothing about 😀

@binary1248
Copy link
Member Author

Fixed.

@LaurentGomila
Copy link
Member

Looks very robust now 😆

What about a helper function to avoid all these repetitions?

bool parseVersionString(const char* prefix, unsigned int versionPosition, unsigned int &major, unsigned int &minor);

@binary1248
Copy link
Member Author

Naaah... an extra function just to move out 4 if statements? 😨

@mantognini
Copy link
Member

It would makes things more readable and shorter. 👍

Maybe even one if statement:

if (parseVersionString(...) || parseVersionString(...) || ...) {
    m_settings.majorVersion = major;
    m_settings.minorVersion = minor;
} else { warning }

with some better formatting, ofc.

@binary1248
Copy link
Member Author

Fixed.

@LaurentGomila
Copy link
Member

Is there a reason to use strncmp with the last argument being strlen of one string? If it stops at the first encountered \0 anyway, maybe we can just use strcmp?

@binary1248
Copy link
Member Author

Using std::strncmp we can check for prefixes. std::strncmp("A", "ABC", 1) will return 0 while std::strcmp("A", "ABC") will return non-zero.

std::size_t versionPosition = std::strlen(prefix);

if ((std::strlen(version) >= (versionPosition + 3)) &&
!std::strncmp(version, prefix, std::strlen(prefix)) &&
Copy link
Contributor

@Foaly Foaly Mar 20, 2018

Choose a reason for hiding this comment

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

I guess the third parameter could be replaced with versionPosition, but it's a minor detail.

@binary1248
Copy link
Member Author

Fixed.

@eXpl0it3r eXpl0it3r added this to Discussion in SFML 2.5.0 via automation Mar 26, 2018
@eXpl0it3r eXpl0it3r added this to the 2.5 milestone Mar 26, 2018
@eXpl0it3r
Copy link
Member

Does it now look okay, @LaurentGomila?

@eXpl0it3r eXpl0it3r moved this from Discussion to Review & Testing in SFML 2.5.0 Mar 26, 2018
@LaurentGomila
Copy link
Member

LaurentGomila commented Mar 27, 2018

Yes, it is.

Just for the sake of arguing, it would replace !std::strncmp(...), which feels like "does not compare", with std::strncmp(...) == 0, which looks more intuitive given that the function returns an integer and not a boolean 😬

And of course we should quickly test this new implementation on OpenGL ES platforms to validate it.

@eXpl0it3r
Copy link
Member

eXpl0it3r commented Mar 27, 2018

@kingnobody8 or @JonnyPtn Can you try the code? Need more of an actual test than review. 🙂

@binary1248
Copy link
Member Author

@LaurentGomila Fixed.

@JonnyPtn
Copy link
Contributor

Looks good to me! tested on iPhone 8

@eXpl0it3r eXpl0it3r moved this from Review & Testing to Ready in SFML 2.5.0 Mar 27, 2018
if (!parseVersionString(version, "OpenGL ES-CL ", m_settings.majorVersion, m_settings.minorVersion) &&
!parseVersionString(version, "OpenGL ES-CM ", m_settings.majorVersion, m_settings.minorVersion) &&
!parseVersionString(version, "OpenGL ES ", m_settings.majorVersion, m_settings.minorVersion) &&
!parseVersionString(version, "", m_settings.majorVersion, m_settings.minorVersion))
Copy link
Contributor

Choose a reason for hiding this comment

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

Sorry for the minor remark, but logical ors || make more sense here, don't they?

Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think so - it's checking that none of the parse attempts work, not that any of them didn't work

@kingnobody8
Copy link

Looks good. Tested on Windows, Android, Mac, and iOS, all successfully.
Just for reference, only the apple versions will do the "old way" of getting the gl version. Windows and android do the "new way".

@eXpl0it3r eXpl0it3r dismissed LaurentGomila’s stale review April 5, 2018 09:23

Issues were resolved

@eXpl0it3r eXpl0it3r merged commit a106573 into master Apr 5, 2018
SFML 2.5.0 automation moved this from Ready to Merged / Superseded Apr 5, 2018
@eXpl0it3r eXpl0it3r deleted the feature/gl_version_parsing branch April 5, 2018 09:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
No open projects
SFML 2.5.0
  
Merged / Superseded
Development

Successfully merging this pull request may close these issues.

None yet

7 participants