PHP regex not working, despite successfully matching in regex101 - php

I'm having the weirdest issue. I've tried referencing other similar answers here, but none seem to fix my issue.
I have the following regex in PHP
/if\s+(?:(.*?)\s*==\s*(?:UrlStatus|DeadURL)|in_array\s*\((?:UrlStatus|DeadURL),\s*(.*?)\s*\))\s*then\s+local\s+arch_text\s+=\s+cfg.messages\['archived'\];(?:(?:\n|.)*?if\s+(?:(.*?)\s*==\s*(?:UrlStatus|DeadURL)|in_array\s*\((?:UrlStatus|DeadURL),\s*(.*?)\s*\))\s*then\s+Archived = sepc \.\.)?/im
It's a messy regex I know, it's supposed to parse code from a module of various versions from different location. It works perfectly in regex101, but preg_match returns false, indicating an error occured. The regex you see is pulled straight from a var_dump. Also pulled from the var_dump is the string being tested. I have included the excerpt that is supposed to match it below.
if is_set(ArchiveURL) then
if not is_set(ArchiveDate) then
ArchiveDate = seterror('archive_missing_date');
end
if "no" == DeadURL then
local arch_text = cfg.messages['archived'];
if sepc ~= "." then arch_text = arch_text:lower() end
Archived = sepc .. " " .. substitute( ```
In the full block of text it takes 81,095 steps to match.
Could it have something to do with that?

Getting a read from preg_last_error(), it returned 6, which maps to the constant PREG_JIT_STACKLIMIT_ERROR.
PHP 7 uses a JIT compiler for preg_match with a small stack size limit. Disabling it allows preg_match to do its job.
This can be done in the php.ini file, or on the fly in the script by using ini_set( 'pcre.jit', false );

Related

How to correctly make conditions in TinyButStrong?

I have to make a template in the TinyButStrong language, but I have no access to the PHP side. I'm just able to modify my template and to upload it on my ERP.
Anyway, the PHP side is working well.
I tried to put an if statement in my ODT template file, but when rendering it doesn't work.
My condition:
[if [tab.product_type]!=1; then ‘[tab.product_ref]’; else ‘0’; block=table:table-row]
I verified value of tab.product_type, and the value is 0 or 1.
I tried many syntaxes, but none is working well. The only thing that it shows is:
.
Where did I make a mistake? I really don't understand, because I tried many syntaxes and I still get this line.
Little update :
I saw that the "when" is more adapted to this usage.
I found a syntax but I'm still having bad results. I made this :
[tab.product_ref;block=table:table-row;when [tab.product_type]!=1]
Anyway, it's giving me lines where tab.product_type is 1.
Why ?? I really don't understand how this language works...

PHP str_replace not replacing a windows path string correctly

$search = 'C:\xampp1.7.7\htdocs\myproject\uploads/files/temp-ds-original';
$subject = 'C:\xampp1.7.7\htdocs\myproject\uploads\files\temp-ds-original\32bd76470cff973ec873d43a4e84dd2f.jpg';
echo str_replace($search, '', $subject);
It just prints $subject without doing any replacements. I thought it could be due to some php version issue as it was on a php 5.3 but then I moved to php 7.2 but still the same result. Not sure what's going wrong here?
Is it something to do with the slashes?
I have hardcoded string values above but in the actual script, I am using $f->getRealPath() to get subject and search. $f is an object of RecursiveIteratorIterator
EDIT
As soon as I posted this question, I could spot the issue as code highlighting made it quite clearer to see that slashes don't match - which means str_replace considers it a non-match. What I am trying to achieve is get relative path which in above example is \32bd76470cff973ec873d43a4e84dd2f.jpg ... the code is here at line 48 https://gist.github.com/bubba-h57/5117694
The above output is on a Windows machine but I will be using this script later on a Linux server. So I need to think about how to get the paths consistent so that str_replace can do the replacement correctly. $search is something I provide manually where $subject is being retrieved automatically using $f->getRealPath().
Update and Answer of my question
I don't believe this question is duplicate to the linked question. People are quick here to show off their skills without paying due attention to details. :)
It turned out to be a simple solution. All I need to do is use realpath() i.e. $search = realpath($search); which gives me the correct result.
Just so that it helps anyone -
$search = 'C:\xampp1.7.7\htdocs\myproject\uploads/files/temp-ds-original';
$subject = 'C:\xampp1.7.7\htdocs\myproject\uploads\files\temp-ds-original\32bd76470cff973ec873d43a4e84dd2f.jpg';
echo str_replace($search, '', $subject);
Output was:
C:\xampp1.7.7\htdocs\myproject\uploads\files\temp-ds-original\32bd76470cff973ec873d43a4e84dd2f.jpg
However I was expecting to be:
\32bd76470cff973ec873d43a4e84dd2f.jpg
I failed to notice the slashes mismatch and therefore str_replace was not at fault at. Importantly, I wasn't trying to get the filename only which I could get from basename() or other methods so I needed to get the slashes right.
All I needed to was to use PHP's realpath() i.e.
$search = realpath($search);
That's it. However, you need to be careful that it only worked for me because I was parsing an actual path i.e. the folder in the $search existed on the disk. So, if you tried to parse a path string which is dummy or not a real directory, realpath() would return empty or false.
you have to do this
you have to use doble backslash if you use only one dont work !
result:
You could just use the same search always
(eg: $search = 'C:\xampp1.7.7\htdocs\myproject\uploads\files\temp-ds-original';)
then change the subject's slashes by using str_replace('/','\',$subject);
Or you could detect the OS and then use the matching $search
You can do this by checking the PHP Constant PHP_OS (Documentation in the link)
I hope that solves it.

Newbe PHP: I'm haveing trouble running simple example code

I'm trying to get some PHP example code to work on PHP version 5.3.4, Apache 2.2.17 on Windows.
The example says I need PHP 4.0 and above with CURL and contains:
<?
$function = $_GET['function-if-exist'];
$test = "Test";
?>
<? =$test ?>
I don't understand why I'm getting the following errors:
My PHP doesn't understand <? and wants <?PHP instead.
My PHP doesn't like <? =$test ?> and wants something like
<?PHP echo $test ?>
$function = $_GET['function-if-exist']; causes the error "Undefined index" but presumably works for the folks that developed it.
Can anyone help me understand why their code is not working for me?
1) <? is the "short tag". Most servers are configured to not allow short tags. This can be changed in php.ini.
2) Again, short tags. Also I think you can't have a space before the =, but the main problem is the short tags setting.
3) $_GET accesses the query string, so when loading your script you need myscript.php?function-if-exist=something
It is more ideal to check if the parameter is set before continuing to prevent errors being thrown, e.g.
if(isset($_GET['function-if-exist']))
{
$functionexists = $_GET['function-if-exist'];
}
the short tag notation is disabled in your php.ini
you need to remove the space before your equal sign
your _get array contains not the expected index, what url do you enter to access the page?
I don't understand why I'm getting the following errors:
My PHP doesn't understand
To be able to use short tags you will have to enable them via config ... http://www.tomjepson.co.uk/tutorials/35/enabling-short-tags-in-php.html
My PHP doesn't like and wants something like
Once you switch on the short tags you will be able to echo using ... important the equals signs must be touching the ? not variable.
$function = $_GET['function-if-exist']; causes the error "Undefined index" but presumably works for the folks that developed it.
The $_GET is populated according to what is in the url. To get a value in $_GET['function-if-exist'] the url accessing the script should be something like mydemo.php?function-if-exist=hello
Hope this helps you
Quick answers to 1 and 2 are enable the short_open_tag option into the php.ini file, for the last one is set the error_reporting to a less strict mode.
The reasons of not to adopt such measures are:
the short tag clashes with the xml declaration and is disabled on different host, if you need to manipulate xml or if you need to write portable code is better to resort to the long tag syntax. You lose the ability to echoing data with = but it is a small annoyance to me.
Warning and notices, as php forgive a lot the programmer for missing variables declaration are a blessing for debug. Keep then raised and you will address a lot of mispellings.
Are you sure that function-if-exist is a correct index for your hash? I would check the index first the access them. If the index don't exists is a probable hint that something is going wrong with your code and you should check the reason of the missing.
Better to stop now, as anyone can write a book on this topic, and several ones already done ;)

Not able to parse this json

I am trying to parse the json output from
http://www.nyc.gov/portal/apps/311_contentapi/services/all.json
And my php json_decode returns a NULL
I am not sure where the issue is, I tried running a small subset of the data through JSONLint and it validated the json.
Any Ideas?
The error is in this section:
{
"id":"2002-12-05-22-24-56_000010083df0188b4001eb56",
"service_name":"Outdoor Electric System Complaint",
"expiration":"2099-12-31T00:00:00Z",
"brief_description":"Report faulty Con Edison equipment, including dangling or corroded power lines or "hot spots.""
}
See where it says "hot spots." in an already quoted string. Those "'s should've been escaped. Since you don't have access to edit the JSON perhaps you could do a search for "hot spots."" and replace it with \"hot spots.\"" like str_replace('"hot spots.""', '\\"hot spots.\\""\, $str); for as long as that's in there. Of course that only helps if this is a one time thing. If the site continues to make errors in their JSON output you'll have to come up with something more complex.
What I did to identify the errors in the JSON ...
Since faulty quoting is the first thing to look for, I downloaded the JSON to a text file, opened in a text editor (I used vim but any full featured editor would do), ran a search and replace that removed all characters except double-quote and looked at the result. It was clear that correct lines should have 4 double-quotes so I simply searched for 5 double-quotes together and found the first bad line. I noted the line number and then undid the search and replace to get the original file back and looked at that line. This gives you what you need to get the developers of the API to fix the JSON.
Writing code to automatically fix the bad JSON before giving it to json_decode() would be quite a bit harder but doable using techniques like those in another answer.
According to the PHP manual:
In the event of a failure to decode, json_last_error() can be used to determine the exact nature of the error.
Try calling it to see where the error is.

php RegEx working on my local server - not working on remote host running php4

I am pretty sure I know what the issue is, but I cannot resolve it for the life of me and I just don't know what to do at this point.
All I am trying to do is qualify the input of a first and last name field. This code IS working on my local server running php5:
<?php
$regex = "John's Jerod";
if (!preg_match("/^[A-Za-z\'\,\.\s]+$/", $regex)) {
echo "ERROR!";
} else {
echo "NO ERROR!";
}
?>
As expected, this returns NO ERROR!, but when I run this on my live server, I only get ERROR with the same data.
I've determined it's the comma throwing it off! And I am pretty sure, because the php version I am running does an auto escape like \' in the name John\'s, so I ran striptags on all output and still the same error.
DOes anyone know what I am doing wrong or how I can resolve this?
I've got about 8 hours in the "bug" as of now. Been through 40+ variations of the RegEex with no luck.
I check and triple checked all of my form field names, vars etc to ensure everything matcheds and all else is OK.
SOS
Try checking specifically for 1. Per the documentation, it returns FALSE (strict check) on error, 0 (strict check) for no matches, or 1 if there is a match (since it stops at one).
Also, per my own preference, I use the ~ symbol for my regex's. And like David Powers said (only he didn't correct it at all), you don't need most of those backslashes (only for the period and the space).
<?php
$regex = "John's Jerod";
if (preg_match("~^[A-Za-z',\.\s]+$~", $regex) !== 1) {
echo "ERROR!";
} else {
echo "NO ERROR!";
}
?>
Hope this helps!
EDIT: Also, you say you're using strip_tags? That strips any HTML tags in a string -- not slashes. You need strip_slashes to strip slashes, not strip_tags ;)
Your regex doesn't need all those backslashes. It should be this:
"/^[A-Za-z',\.\s]+$/"
Also, you refer to using striptags(). You should be using stripslashes() if your server has magic quotes enabled.
[Edited regex]

Categories