6

This may be too obscure of an question, but I've been troubleshooting a baffling server error for hours and have pinned it down to the most bizarre issue; at this point I just want to know if anyone has ever had something similar occur, or might have any insight into what might possibly be happening.

The following line of code is triggering the error:

if ($Name=='ProxiedIP') { return true; }

This version runs without any problem at all:

if ($Name=='proxiedIP') { return true; } 

It seems like somehow the token 'ProxiedIP' is fouling something up, but I cannot even think of how a string literal would be translated by the parser in a way that could hang the server up like this. BTW, I know for certain that $Name!='proxiedIP' and $Name!='ProxiedIP'.

Here's the entry in the apache error log:

[Fri Jan 18 18:15:12.924419 2013] [core:error] [pid 27676:tid 3427232831232] [client 12.345.67.890:34482] Premature end of script headers: index.php, referer: http://mySite.com/

I searched for 'ProxiedIP' as a keyword for every component that I can think of on my system and I'm coming up with nothing. The more imperative question for me though is how a string could somehow have this impact in a comparison check. Any ideas?


Also noteworthy that the PHP error log is completely silent about it. I'm enabling error output at the top of the page, but the script never finishes loading so that may be a factor. Here's how I'm setting it:

error_reporting(E_ALL);
ini_set('display_errors', 1);

Because the code worked here, it seems more likely that it could be something specific to the platform implementation. I'm running this on an instance of Gandi.net's 'Simple Hosting' service, which runs Varnish for application acceleration. It may also be worth mentioning that the code is being loaded in an iframe in a separate domain.

I am also doing some intensive work with the headers, and this seems like the greatest potential source of the problem, although the strange thing as far as I'm concerned is the way the error is being triggered. Also, there's no common header that I'm aware of called 'ProxiedIP', although that use conflict is the only thing that seems like it could make sense so far. Regardless, I don't see it.

To me, the real item of relevance is the mere fact that a string comparison is crashing the server. I've been programming in PHP for over 10 years and I have never had anything like this happen before. I'm trying to understand the logistics behind how it could even happen.


Update: I've tried the following variation, and it still produces the same result:

if ($Name === (strtoupper("p").'roxiedIP')) { return true; }

It was asked whether I would post the full code, but the script for the iframe side is 1400+ lines long so that's not really feasible. I'm adapting the segment in question to try running it in a new script though and will post the results.

pnuts
  • 58,317
  • 11
  • 87
  • 139
jtrick
  • 1,329
  • 18
  • 23
  • What have you tried? Also if you are comparing two strings, you should use === – Hydra IO Jan 18 '13 at 23:57
  • 1
    [Works for me.](http://codepad.org/Dx4dtVya) Maybe print errors instead of hiding it behind the generic 500? – Matchu Jan 18 '13 at 23:57
  • @HydraIO Why `===` over `==`? – John V. Jan 19 '13 at 00:00
  • I'll try all of the above. So this doesn't seem completely unexpected that a string comparison could halt script output? – jtrick Jan 19 '13 at 00:01
  • 2
    @AlexLunix: [Here's one great reason why.](http://codepad.org/qKSl3U61) – Matchu Jan 19 '13 at 00:03
  • 1
    @AlexLunix here is another example http://www.phpcatalyst.com/php-compare-strings.php – Hydra IO Jan 19 '13 at 00:04
  • http://stackoverflow.com/questions/4336757/500-server-error-premature-end-of-script-headers – Frank Farmer Jan 19 '13 at 00:05
  • 3
    What happens when you put the literal `ProxiedIP` anywhere else in your program? As a string literal? As a function? A comment? Anything exceptional happens? – Madara's Ghost Jan 19 '13 at 00:06
  • 1
    please post the full code – Nir Alfasi Jan 19 '13 at 00:10
  • try `$Name === strtoupper("p") . "roxiedIP"` too – Janus Troelsen Jan 19 '13 at 00:17
  • Are you building the page headers through your code? Or manipulating/parsing/interpreting it? (If yes to any, post that code). – MrLore Jan 19 '13 at 00:18
  • What is $Name? A string or an Object? Try a var_dump of $Name; is there perhaps a PHP class Name? – JvO Jan 19 '13 at 00:18
  • == is case sensitive so the two variants you list will have different execution paths. One fails and one doesn't. – TerryE Jan 19 '13 at 00:37
  • @TerryE: It's true, but in this case they should both fail. – jtrick Jan 19 '13 at 00:38
  • @MrLore: Yes, I am doing both. Unfortunately the complexity and volume of code behind the process makes it too unwieldy to post here. I'm trying to recreate the issue in a more manageable form and so far have been unsuccessful. I think the direction you're pointing to is the right one though. – jtrick Jan 19 '13 at 01:07
  • @Janus I updated the question with your idea. Unfortunately, same result. – jtrick Jan 19 '13 at 01:09
  • if you really don't mind posting the source, use a [pastebin](http://gist.github.com). just put a link to it from here. – Janus Troelsen Jan 19 '13 at 01:27
  • @jtrick, you say that " I know for certain that $Name!='proxiedIP' and $Name!='ProxiedIP'" if that's the case why not just use a case -insensitive match: `if( is_string($Name) && strtolower($Name) == 'proxyip')`. Janus' idea of `strtoupper("p") . "roxiedIP"` is daft. This is just == "ProxiedIP"; it's still a case sensitive comparison. – TerryE Jan 20 '13 at 11:52
  • @TerryE, I figured it was worth a try considering the bizarre nature of the way it seemed the error was being triggered. I even thought the parser could somehow be tokenizing a string literal, so the modification was as valid as any under this impossible scenario. Thanks for your input, but the reason for the trigger turned out to be unrelated to the direct comparison and only affected because of details involving debug_backtrace(), self-referencing arrays, and ReflectionClass... – jtrick Jan 20 '13 at 15:19

4 Answers4

2

I think the problem is with the variable $Name. Check whether it is getting assigned properly. Also check the code after if statement which is causing the problem.

nbbk
  • 1,102
  • 2
  • 14
  • 32
1

Actually, I think your problem lies in the calling function, i.e. depending on the return value it does something "stupid" and PHP crashes. Try replacing the if() with a hard return true or return false and see what happens.

JvO
  • 3,036
  • 2
  • 17
  • 32
  • The case where it works (lowercase p) would suggests that it handles the return value just fine. – ta.speot.is Jan 19 '13 at 00:03
  • Good insight, but the slightly modified version returns with no issue at all. BTW, I know for certain that $Name!='proxiedIP' – jtrick Jan 19 '13 at 00:03
1

As i get from your error, you are messing up the framework, the change in that if of yours triggers some output being called before the fw is allowed to make output. Just read it in more detail, you got it on the wrong train, that is not the cause of the error, it is the beginning of an unhallowed state of the fw.

Try running the script in a php debugger rather then using var dump.

Sangoku
  • 1,588
  • 2
  • 21
  • 50
  • I agree that this seems like the most likely cause. I'm trying to recreate the sequence under more controlled conditions and so far have been unsuccessful with that. It's noteworthy that there is no header that I'm working with called 'ProxiedID', but this seems like the best lead so far. – jtrick Jan 19 '13 at 01:20
  • Just had an idea, about your problem, i once came across a situation where the variable that should contain the sting contained a object. Try to var_dump the variable to see what it contains when it crashes. – Sangoku Jan 19 '13 at 09:04
1

Thanks for the posts, but it turned out to be a really convoluted scenario, where conditions several levels down the function chain caused unexpected behavior outside the scope of either function in question.

The actual issue was due to a condition check while parsing through output of a debug_backtrace() array in a totally separate process, which ironically was in place to prevent infinite recursion and instead triggered a similarly disruptive cascade of events that overran the allocated memory limit.

I originally posted because I was baffled by what truly seemed to be a string literal comparison doing something I didn't think should be possible, and wanted to understand what conditions could allow it to happen if so. I'm just glad the cause wasn't actually what it seemed to be. Thanks for helping to solve the puzzle.


Update: The true source of the error hinges on PHP's difficulty translating objects or arrays that contain references to themselves. I'm storing converted headers, direct header references, $_REQUEST[] and $_SERVER[] items, as well as logging messages and associated data in complex associative arrays. There are a lot of dynamic references between these items, particularly those involving the native PHP globals which I've made use of.

PHP has traditionally had problems managing self-referencing entities, and although improvements have been made, my particular situation is complex enough to send ReflectionClass into an endless loop while attempting to map these objects. I've fixed it by manually dereferencing the items as I'm polling them, but it's something to be aware of if needing to work with multiple $GLOBALS-related vars within a common array or referencing structure.

jtrick
  • 1,329
  • 18
  • 23