What does {0} mean in a PHP statement? - php

Apols if this has been asked before. I am using someone else's PHP code and came across the following line:
if($_GET['file']{0}=='.') die('Wrong file!');
The if, $_GET and die I understand, but what is the meaning of the {0} after the $_GET['file']? I've looked through a number of tutorials and didn't come across the answer.
TIA.

$str{0} will return the first character/byte of a string. But the syntax $str{0} is deprecated in favor of $str[0]:
Note: Strings may also be accessed using braces, as in $str{42}, for the same purpose. However, this syntax is deprecated as of PHP 5.3.0. Use square brackets instead, such as $str[42].
If you’re working with multi-byte characters, use mb_substr instead.

The {0} is the same as [0]. So, $_GET['file']{0} is getting the zeroth character from $_GET['files'].

It's shorthand for accessing the first character of the string. $_GET['file']{1} would be the second character, and so on. So in your example it's checking to see whether the first character is a dot, and if so, exiting; presumably to avoid people passing paths in the URL such as ../../../etc/passwd.

As others have said, it's looking at string position 0 in the variable $_GET['file'] and throwing an error if that happens to be a dot.
This looks like a (relatively crude) way of preventing hack attacks by blocking the user if he tries to access a file that starts with a dot.

Related

Differences in backslashing between Notepad++ and PHP

EDIT: I found a solution I didn't expect. See below.
Using regex via PHP's preg_match_all , I want to match a certain url (EDIT: that is already escaped) in a string formatted as json. The search works wonderfully in Notepad++ (using regex-matching, of course) but preg_match_all() just returns an empty array.
Testing on tryphpregex.com I found out that somehow my usual approach to escaping a backslash gives a pattern error, i.e. even the simple pattern https:\\ returns an empty result.
I'm utterly confused and have been trying to debug for too long so I may miss the obvious. Maybe one of you can see the simple error?
The string.
The pattern (that works fine in Notepad++, but not in PHP):
%(https:\\/\\/play.spotify.com\\/track\\/)(.*?)(\")%
You don't need to escape the slash in PHP %(https://play.spotify.com/track/)(.*?)(\")%
The Backslash before doule quote is only needed if you enclosures are double quotes too.
Found a solution to my problem.
According to this site, I need to match every backslash with \\\\. Horrible, but true.
So my pattern becomes:
$pattern = "%(https:\\\\/\\\\/play\.spotify\.com\\\\/track\\\\/)(.*?)(\")%";
Please observe that I tried to find a pattern inside a string that didn't contain clear urls, but urls containing escape characters (it was a json-output from spotify)

Confusion with ereg_replace() Beginning PHP and MySQL Example by W Jason Gilmore

Just a note to begin I am aware that ereg_replace() is deprecated, since POSIX is no longer being used. But in "Beginning PHP and MySQL" by W Jason Gilmore, Gilmore emphasizes that although POSIX isn't to be used, an understanding is still necessary as a means of conversion to Perl. So once again I understand it's deprecated but since I'm trying to understand everything in the book I might as well understand this.
So the example is as follows:
<?php
$text = "This is a link to http://www.example.com/.";
echo ereg_replace("http://([a-zA-Z0-9./-]+)$", "\\0",
$text);
?>
//Output
This is a link to http://www.example.com/..
So I understand the majority of code in the above example, my problem lies with the ./- and the output. For the ./- I tried to think according to quantifiers where . = between, so everything between [:alnum:] and / is replaced. I also thought maybe ./- are characters within the range which would also be replaced since [:alnum:] doesn't include punctuation. For verfication I looked at the output but theres no - present. If only the / is replaced than the code would make sense, since /0 outputs http://www.example.com/ but than the problem lies with the missing - which I presume to be pertinent to the brackets rather than as a quantifier.
My other question is in regards to the output, if the function returns the string with the modified string why does the period which was present in the original string appear after the second /0, not the first, if its the original text, why does the tag follow it and not precede it?
Just for some quick background, I have a basic understanding of php,html,css,javascript,C++ and I'm reading this for a more in depth understanding of php and an introduction to MySQL, so unfortunately explanations which are entirely advanced code/concepts go right over my head.
why does the period which was present in the original string appear after the second /0, not the first
This is not the case, because the actual output is:
This is a link to http://www.example.com/.
The period is included in both the attribute as well as the tag contents.
my problem lies with the ./- and the output
When present inside a character set, ./- means to match either a period, forward slash or a dash; it's important to note that the dash must appear at the end of the character set to avoid ambiguity.

What could the purpose of replacing %20 with spaces before doing PHP rawurlencode() be?

It's a pretty silly question, sorry. There is a big and rather complex system that has a bug and I managed to track it down to this piece
return str_replace('%2F', '/', rawurlencode(str_replace('%20', ' ', $key)));
There is a comment explaining why slashes are replaced - to preserve path structure, e.g. encoded1/encoded2/etc. However there is no explanation whatsoever why %20 is replaced with space and that part is the direct cause of a bug. I am tempted to just remove str_replace() but it looks like it was placed there for some reason and I have a feeling that I'll break something else by doing this. Has anyone encountered anything similar? Perhaps it's a dirty fix for some PHP bug? Any guesses and insights are highly appreciated!
Doing so would prevent %20 (encoded space) from being encoded to %2F20. However, it only serves to prevent double escaped spaces; other special characters would still get double encoded.
This is a sign of bad code; strings that are passed into this function shouldn't be allowed to have encoded characters in the first place.
I would recommend creating unit tests that cover all referencing code and then refactor this function to remove the str_replace() to make sure it doesn't break the tests.
First thing that jumps to mind is as a mitigation technique against double encoding.
Not that I would recommend doing such a thing this way, as it would get real messy real quickly (and one would already wonder why only that entity, perhaps 'they' never experienced issues with any others... yet).
It could be the result of a misunderstanding of rawurlencode() vs urlencode()
urlencode() replaces spaces with + signs
If the original author thought that rawurlencode() did the same thing, they would be attempting to pre-encode the spaces so they don't get turned into +s

preg_replace(), no ending delimiter '$' found

Alright, this problem seems to be way above my head!
I have this code:
$request=preg_replace('$(^'.str_replace('$','\$',$webRoot).')$i','',$requestUri);
This throws me an error:
preg_replace(): No ending delimiter '$' found
But here's the thing, that ending delimeter is certainly there.
After that function call I echoed out the following:
echo $webRoot;
echo $requestUri;
echo '$(^'.str_replace('$','\$',$webRoot).')$i';
This is the result of those echoes:
/
/en/example/
$(^/)$i
What is funny is that if I do this directly:
preg_replace('$(^/)$i','',$requestUri);
..it works. But this also fails:
$tmp=str_replace('$','\$',$webRoot);
preg_replace('$(^'.$tmp.')$i','',$requestUri);
And just to be thorough, I also tested what echo $tmp gives, and it does give the proper value:
/
Is it a bug in PHP in Windows? I tried it out on Linux server and it worked as expected, it didn't throw this error. Or am I missing something?
Just to make sure, I even updated PHP to latest Windows version (5.4.2) and the same thing happens.
Well, I personally would use another character as a delimiter like '#' since the $ char is a regexp special char which matches at the end of the string the regex pattern is applied to. That said the few times I had to work on windows servers I found that every regular expressions has to be passed through preg_quote function, nevermind if it contains or not regexp special chars.
$request=preg_replace('#(^'.preg_quote($webRoot).')#i','',$requestUri);
abidibo's answer is correct, but apparently the problem was caused by a bug in str_replace() function. For some reason, in Windows Apache and nginx, this function corrupts the string and pads it with symbols that cannot be read.

replicate preg replace with javascript

Is it possible to replicate this with javascript?
preg_replace('/(.gif|.jpg|.png)/', '_thumb$1', $f['logo']);
EDIT - I am not getting this following error for this peice of code,
unterminated string literal
$('#feed').prepend('<div class="feed-item"><img src="'+html.logo.replace(/(.gif|.jpg|.png)/g, "_thumb$1")+'"/>
<div class="content">'+html.content+'</div></div>').fadeIn('slow');
There are a couple of problems with the code you are trying to replicate:
It matches "extensions" even if they aren't at the end of the filename.
The dot in a regular expression matches (nearly*) any character, not just a period.
Try this instead:
'abc.jpg'.replace(/\.(jpg|gif|png)$/, '_thumbs$&')
I'm assuming that the string you are trying to replace contains only a single filename.
*See the documentation for PCRE_DOTALL.
Yes, except that in JavaScript, replace is a string's method, so it would be rearranged a little (also, the array/object notation is slightly different):
f.logo.replace(/\.(gif|jpg|png)/, '_thumb.$1');
more info
somestringvar.replace(/(.gif|.jpg|.png)/, replacementValue)

Categories