Wow, StackOverFlow does a great job even AJAX search of topics and answered questions as I type in the title. Truly worthy programmers.
The code follows. It works just fine, when I set max recursion to 0. So it seems obvious that the problem is in my recursion code. But i can't find it.
I considered that opendir might return a handle that is global and I was stepping on it in the next recursion, so I set the recursion outside the opendir handle. No recursion is called with a handle open and it still produces nothing when max recursion is more than zero. I even added a max opened dir. As you see that variable pass down through the recursions, it will not opendir if $maxopendir is zero. If that were the problem, I would still get something back. But I get nothing, unless of course $maxrecursions is 0, then its fine and returns all files or directory names in HOME directory that match the search term.
Any experts on recursion that can correct me?
$dircontent.= searchalldirectories(HOME, $_POST['search'], 0, 5);
function searchalldirectories($directory, $seachterm, $maxrecursions, $maxopendir){
$dircontent= '';
$dirs= array();
if ($maxopendir>0){
$maxopendir--;
$handle= opendir($directory);
while (($dirlisting= readdir($handle))!==false){
$dn= ''; $fn= ' File';
if (is_dir($directory.'/'.$dirlisting) && $maxrecursions>0){
$dirs[count($dirs)]= $directory.'/'.$dirlisting;
$dn= '/'; $fn= 'Dir';
}
if (stripos($dirlisting, $seachterm)!==false){
$dircontent.= '<input type="image" src="go.jpg" name="cmd" value="home:/'.$dirlisting.'"> '.$fn.':// <b>'.$dirlisting.$dn.'/</b><br>';
}
}
closedir($handle);
for ($i=0; $i<count($dirs); $i++){
$dircontent.= searchalldirectories($dirs[$i], $s, ($maxrecursions-1), $maxopendir);
}
}
return $dircontent;
}
Your loop appears to be running away with itself when the opendir fails. You may try testing the return value like so:
if(!($handle= opendir($directory))) {
echo "Could not opendir($directory)\n";
return false;
}
Related
So I'm making a webshop, well, trying to atleast for a course project using WAMP. But when trying to register new users and in the process checking their password against a list of common ones the use of fgets() returns an empty string.
if(empty(trim($_POST["password"]))){
...
} elseif (!checkPassword($_POST["password"])) {
$password_err = "Password to common.";
echo "<script>alert('Password to common.'); location.href='index.php';</script>";
}
The checkPassword() is where the fault lies.
function checkPassword($passwordtocheck) {
$passwordtocheck = strtolower($passwordtocheck);
$common_passwords = fopen("commonpasswords.txt", "r");
while(!feof($common_passwords)) {
$check_against = fgets($common_passwords);
echo "<script>alert('Checking $passwordtocheck against $check_against.'); location.href='index.php';</script>";
if($check_against == $passwordtocheck) {
fclose($common_passwords);
return false;
}
}
fclose($common_passwords);
return true;
}
Lets say that I input the password 12345678 when registering, then the scripted alert will say "Checking 12345678 against ." and send me back to index.php. So it looks like it doesn't succeed in reading the file at all. The commonpasswords.txt is in the same folder as the rest of the files and with a single password on each row.
And there is no problem opening the file to begin with either, if I do this instead:
$common_passwords = fopen("commonpasswords.txt", "a");
fwrite($common_passwords, "test");
'test' will appear at the bottom of the file under the existing words on its own row without a hitch. And this is where I'm at, would appreciate whatever input people can give!
EDIT; I do understand that this probably breaks a ton of good-practice 'rules' in general and regarding security. But the website is not really supposed to function or look good, it just need to barely work so that we can later try and use different methods of attacking it and the connected database.
If you insist on doing this yourself – which I do not recommend – you can simplify things a lot by using the file() function. This returns an array of every line in the file. Then use array_filter(); it runs a callback on each element of the array where you can check if there's a match with your password. If the callback returns false, the element is removed from the array. After that, if you have any elements left you know there was a match.
function checkPassword($pwd) {
$pwd = strtolower($pwd);
$common = file("commonpasswords.txt", FILE_IGNORE_NEW_LINES);
$results = array_filter($common, function($i) use ($pwd) {return $i == $pwd;});
return count($results) === 0;
}
But really, there are dozens of libraries out there to check password strength. Use one of them.
Or, as pointed out in the comment, even simpler array_search:
function checkPassword($pwd) {
$pwd = strtolower($pwd);
$common = file("commonpasswords.txt", FILE_IGNORE_NEW_LINES);
return array_search($pwd, $common) === false;
}
I'm fixing up some old code that is supposed to create a directory for a customer based on the customer's last name. 999 out of 1000 times it works as expected but every now and then I get an "Unable to create base directory" error message and the debug shows me that the $file_directory in that case is simply "Array" instead of something like "\\network\path\order_data\1234567890_Smith".
Could anyone explain how this code could work the vast majority of the time but still consistently fail about .1% of instances? Or is it something other than the code? Thanks!
Note: I did not originally write this code but am tring to leave it as close to the original as possible
Edit I had a typo in my previous code but I think tliokos and Fluinc had a very good point but just wanted to fix my mistake
Code:
<?php
$file_directory = build_directory($customer, $UID);
if(!is_dir($file_directory)){ //Check to make sure it does not already exist
if(!mkdir($file_directory)){
mail("debug#example.com","Unable to create base directory","$file_directory");
}
}
function build_directory($customer, $UID){
if($customer->related_orders){
$related = explode(",", $customer->related_orders);
foreach($related as $r_UID){
$rel_order = get_order($r_UID); //fetches order object
if((isset($rel_order->file_directory) && $rel_order->file_directory != "")){
return $rel_order->file_directory;
}
}
}
//Here is where I made my correction
$paths = array('\\\\network\\path');
$base = $paths[0];
//Test if directory is already assigned
if(is_dir($base . "\\order_data\\".$UID."_".str_replace(" ","_",$customer->last_name)."\\")){
return $base . "\\order_data\\".$UID."_".str_replace(" ","_",$customer->last_name)."\\";
}
if($base){
return $base . "\\order_data\\".$UID."_".str_replace(" ","_",$customer->last_name)."\\";
}
}
?>
Change $base = array('\\network\path');
To $base = '\\network\path';
I think the problem is in the build_directory() function and more specifically after the first if.
So if the customer has no related orders, you are trying to concatenate an Array with a string and the result is like
Array\order_data\....
Try o change
$base = array('\\network\path');
to
$base = '\\network\path';
So the problem ended up being framework/user related.
We discovered that if the user refreshed the page during the directory creation it would create the same directory twice which our framework would save as an array of identical paths.
I have written the following code for finding n!. I am running this through CLI.
<?php
$handle = fopen("php://stdin", "r");
$number = (int) trim(fgets($handle));
$fact = calcFactorial($number);
echo $fact . "\n";
function calcFactorial($number) {
if ($number < 2) {
return 1;
} else {
return $number * calcFactorial($number - 1);
}
}
fclose($handle);
?>
The above code is working fine. But there are two issues with two different PHP installations.
On one PC I get,
Fatal error: Maximum function nesting level of '100' reached,
aborting!
To correct above problem I find the solution here. Is this the correct way to have a solution? Because it depends on a particular Default Value of 'xdebug.max_nesting_level' .
On other PC I get,
INF
So what is the best approach to tackle this issue?
P.S.: I have gone through various solutions throughout this website but I am not able to conclude.
UPDATE: There is one function suggested. But can it be done without using any kind of function?
Nesting limit:
if the calcFactorial() can by non-recursive then you can change it to this:
function calcFactorial($number){
if($number<2){
return 1;
}
$ret = 1;
for($i=2;$i<=$number;$i++){
$ret = $ret*$i;
}
return $ret;
}
if has to be recursive you never be able to calc factorial of number bigger then Maximum function nesting level.
INF:
That means PHP thinks number is infinitive (to big to store in memory) ... i think (not sure) that answer is bigger than PHP_INT_MAX ...
You can confirm this by echo is_infinite($number);
you can try solve this with storing numbers as strings (of digits) or arrays (of digits) and than write some function to make multiplication of this strings (arrays) but it is not easy to do
I'm building a dynamic website, but the pages are not showing up because of the error
Fatal error: Function name must be a string php
on the line
$p= $_GET('p');
The whole code for including the files is
$folder = 'de/';
$folder = 'en/';
if(!empty($_GET['p'])){
$pages = scandir($folder,0);
unset($pages[0],$pages[1]);
$p= $_GET('p');
if(in_array($p.'.inc.php', $pages)){
include($folder.'/'.$p.'.inc.php');
}else{
echo 'error message';
}
}else{
include($folder.'home.inc.php');
}
What's wrong with my code?
UPDATE
I've updated the code, but now i get the error
*failed to open stream: No such file or directory*
I'm working on a local server.
$p= $_GET('p');
should be
$p= $_GET['p'];
Your code is quite inefficient. Why slurp up the directory's contents into an array and then search the array when you could simply have:
if (isset($_GET['p']) {
$file = $folder . $_GET['p'] .'.inc.php';
if (is_readable($file)) {
include($file);
} else {
die('error');
}
} else {
include($folder.'home.inc.php');
}
This is BY FAR simpler than your convoluted logic. It is however, also vulnerable to the exact same vulnerability: you're allow the user to specify a full path to ANY *.inc.php file on your server for which they know the path name. Depending on your setup, this could allow the user to include files which you ever intended to be executed in this manner and leak internal details of your system/configuration.
$p= $_GET('p');
You really didn't notice that you were using parenthesis?
Use:
$p = $_GET['p'];
$p= $_GET('p'); it should be $p= $_GET['p'];
The error seems $_GET('p') should be $_GET['p'] instead.
A few considerations:
The if(!empty($_GET['p'])), could be changed to if (array_key_exists('p', $_GET) && !empty($_GET['p']) instead. PHP always complain about array indexes and it's a good way to prevent it.
on unset($pages[0],$pages[1]);, if the array doesn't return 2 elements, it will return null and PHP unset function will complain. A better way could you check if there are elements on $pages variable;
In case of scandir doesn't return any element, not sure if it'll return null or array, so in this case if(in_array($p.'.inc.php', $pages)) will throw a error.
Cheers
I use the latest code igniter (2.0.3) and php-active 0.0.1.
All are working fine except save();
Code:
if($_POST)
{
$entry= Customers::find_by_routeid('4');
$entry->routeid=5;
$entry->save();
}
Here's my problem: for some reason that I cannot understand the above code does not work, but if I take the code out of if ($_POST), it works fine.
What I am doing wrong?
EDIT:
Thanks Damien Pirsy $this->input->post() does the trick, but when I uncomment the comments in the code the problems returns.
The code now is:
if($this->input->post())
{
$id = $this->input->post('id');
$oldRoute = $this->input->post('oldRoute');
$newRoute = $this->input->post('newRoute');
$entry= Customers::find_by_routeid($this->input->post('oldRoute'));
$entry->routeid=$this->input->post('newRoute');
$entry->save();
/*
if($oldRoute<$newRoute)
{
for ($i=$newRoute; $i>$oldRoute; $i--)
{
$element = Customers::find_by_routeid($i);
echo $element->routeid -= 1;
$element->save();
}
}
*/
}
The elements new IDs ($element->routeid -= 1;) are echoing right, but I have the same problem as in the beginning and neither of two saves work.
You didn't provide much details or debug info, so I'll just guess: try using the CI's native post handler instead. You should have var_dump()ed the $_POST array, see if isset() or not, also, since you're using it as a condition
if($this->input->post())
{
//...
}
UPDATE:
Since we're talking about Post variables, don't assume they're exactly as you want them. Keep in mind that $this->input->post('field') returns FALSE when the index is not present; that might well brake your if condition.
Assuming you need numbers to do this, you can do a check like
if($this->input->post('newRoute') AND is_numeric($this->input->post('newRoute'))
{
$newRoute = $this->input->post('newRoute');
}
else
{
// give it a default value, or raise an error, for example. If you need this
// variables, and need them to be numbers, you cannot go on in case these
// conditions are not met, right?
}
And the same for $oldRoute.
And yeah, OK, maybe you can write a cleaner code than mine, but you get the picture ;)