Skip to content

Make exception messages and error output binary safe #413

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 5 commits into from

Conversation

LawnGnome
Copy link
Contributor

This will probably need an RFC, but until I have time to write one, this PR will have to do to track this.

Previously, exception messages were documented as not being binary safe. The reality was actually more complicated than this: Exception::$message itself was binary safe if accessed through Exception::getMessage(), but wasn't binary safe when the full exception string was constructed by Exception::__toString().

I dislike arbitrary restrictions and inconsistent behaviour, hence this PR.

9b1069f removes the exception restriction. By itself, that still isn't all that useful, since error output also isn't binary safe. The follow up commits remove that restriction (of course, if your actual stdout/stderr aren't binary safe, you have lost regardless).

Things that would still have to be dealt with before this became mergeable:

  • Windows testing. The actual code change in main/main.c is pretty mechanical, but I don't know how it'll behave in Windows' weird console.
  • This is going to be slower, due to the additional printf calls and the additional mallocs and frees in Exception::__toString(). Is that really a problem in practice? Error and exception code aren't speed demons at the best of times.
  • The fact that error output now comes in multiple chunks may cause problems (although honestly, I'd hope not in practice).
  • This would be the first code in Zend/ to use the %Z printf modifier. I presume there is a reason why this has been avoided until now, although I have no idea what that reason might be. This could be worked around if needed.

@nikic
Copy link
Member

nikic commented Aug 20, 2013

Maybe a better solution would be to add a new printf modifier for printing a string with length? I mean, in PHP that's really common, but right now we always have to use PHPWRITE for it (for output) or manually copy (for string). Seems rather suboptimal.

str[len] = '\0';

efree(prefix);
efree(suffix);
Copy link
Member

Choose a reason for hiding this comment

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

Couldn't you use %Z here too?

  len = zend_spprintf(&str, 0, "exception '%s' with message '%Z' in %s:%ld\nStack trace:\n%s%s%s",
            Z_OBJCE_P(exception)->name, &message, Z_STRVAL(file), Z_LVAL(line),
            (trace && Z_STRLEN_P(trace)) ? Z_STRVAL_P(trace) : "#0 {main}\n",
            len ? "\n\nNext " : "", prev_str);

@nikic
Copy link
Member

nikic commented Aug 20, 2013

Of course %Z covers many of the cases already, so maybe we should just start using that more (unless there is some reason why we don't do that ^^). Having a modifier for string-with-length is still useful though if you don't have a zval, e.g. the buffer and buffer_len in the error handling code (or more obscurely: in the exception code Z_OBJCE_P(exception)->name is printed without binary safety and should ideally make use of Z_OBJCE_P(exception)->name_length).

@smalyshev
Copy link
Contributor

Adding it to php sprintf won't help the case with fprintf though.

@php-pulls
Copy link

Comment on behalf of krakjoe at php.net:

Since this PR has merge conflicts, seems to have been abandoned by author, and since it would seem at least partially unnecessary, I'm closing this PR.

Please take this action as encouragement to work on this feature, if you think it valuable.

Please ensure any new PR has satisfactory test coverage, and ensure those tests pass.

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.

4 participants