I have been given 2 dll's.
The first encrypts a string.
The second, decrypts an encrypted string.
I do not know how it works this dll.
Also I have been given a code example in .net (Don't know .net)
dll_decrypt_.Decrypt myuser = new dll_decrypt.Decrypt();
user = myuser.DecryptString(userEncrypted);
I have searched among the web, but still cant' find the answer.
Also I have added the 2 dll's to the ext folder in wamp:
C:\wamp64\bin\php\php7.0.32\ext
And added the "extension=dll_decrypt.dll" into the php.ini file both in apache and php folders.
This would be my php code:
try
{
$dll = new COM('dll_decrypt.Decrypt');
$dll->Function();
}
catch(Exception $e)
{
echo 'error: ' . $e->getMessage(), "\n";
}
I expect to get the decrypted string so I can see the user.
I have a Windows 7 dev environment and I am using symlinks (not junctions) with php's symlink() function. Everything works fine until a target of a symlink gets deleted. When that happens all the PHP's file functions (file_exists(), is_file(), is_dir(), is_link(),...) return false although the symlink is still there.
This gets even more troubling if the broken symlink was originally targetting a directory. I can do file_put_contents() on the symlink path, which creates a file on the original target directory path. That's quite unfortunate and unpredictable.
So to my question: is there a way to detect a broken symlink in PHP on Windows 7 environment? I need whatever decent solution possible (an exec() or something like that). The production server is running standard LAMP configuration which works fine as expected.
I am using XAMPP with PHP 5.5.3.
A sample script:
$dir_path = __DIR__ . '/temporary_directory';
$link_path = __DIR__ . '/broken_symlink';
mkdir($dir_path);
symlink($dir_path, $link_path);
rmdir($dir_path);
echo 'file_exists(): ';
var_dump(file_exists($link_path));// false
echo "<br>\n";
echo 'is_file(): ';
var_dump(is_file($link_path));// false
echo "<br>\n";
echo 'is_dir(): ';
var_dump(is_dir($link_path));// false
echo "<br>\n";
echo 'is_link(): ';
var_dump(is_link($link_path));// false
echo "<br>\n";
echo 'readlink(): ';
var_dump(readlink($link_path));// false
echo "<br>\n";
// Now it is possible to create file:
file_put_contents($link_path, '');
// which creates a new file on the $dir_path. That makes the symlink somewhat hybrid as Windows Explorer thinks it is a directory symlink but it points to a file (so it's unable to resolve it).
I have come up with a solution. I am not completely happy about it but it should work.
function is_link_on_windows($path) {
$parent_dir_path = dirname($path);
if (false === file_exists($parent_dir_path)) return false;
$filename_regex = preg_quote(substr($path, strlen($parent_dir_path) + 1), '#');
// DOS' dir command is unlike PHP sensitive about the path format.
$parent_dir_path = realpath($parent_dir_path);
exec('dir ' . $parent_dir_path, $dir_output);
foreach ($dir_output as $line) {
// Symlink's entry should look like this:
// broken_symlink [C:\xampp\htdocs\symlink_test\temporary_directory]
// where the part within square brackets is the symlink's target.
if (preg_match('#\\s' . $filename_regex . '\\s\\[[^\\]]+\\]#', $line)) {
return true;
}
}
return false;
}
I was wondering what's wrong with my code, if I use clamscan, it works fine both reading from /tmp, or manually specified the path. but if I use clamdscan, any path from /tmp will result in error (the int result is 2). This is the code.
$command = 'clamdscan ' . escapeshellarg($_FILES['file']['tmp_name']);
$out = '';
$int = -1;
exec($command, $out, $int);
echo "\n" . $command;
echo "\n" . $out;
echo "\n This is int = " . $int;
if ($int == 0) {
// all good, code goes here uploads file as normal IE move to
//echo "File path : ".$file."Return code : ".cl_pretcode($retcode);
//echo "\n";
move_uploaded_file($_FILES["file"]["tmp_name"], "filesave/" . $_FILES["file"]["name"]);
echo "Stored in: " . "filesave/" . $_FILES["file"]["name"];
} else {
echo "\n FAILED";
}
based on above code, it will failed because $int = 2. But, if I change the command to
//some file that is saved already in the directory
$command = 'clamdscan ' . '/abc/abc.txt';
It works perfectly fine.
It only failed if the command is clamdscan. if I use clamscan, temp directory is fine
any idea?
You should really just use one of the many clamd clients out there instead of relying on exec'ing a command and parsing its output, that's super fragile and will bring you nothing but headache in the future. For example:
http://torquecp.sourceforge.net/phpclamcli.html
If you are the do-it-yourself type, the clamd wire protocol is super simple (http://linux.die.net/man/8/clamd) and you could potentially write up a simple client in a couple of hours. Again, the benefit here is that it's a well defined protocol and has some nice features like a streaming call that allows you to operate the clamd service and your webapp with completely difference security credentials (heck they can even run on different boxes).
I hope this helps.
Just a quick remark on using http://torquecp.sourceforge.net/phpclamcli.html as a supposedly better alternative to a DIY cli exec. The aforementioned php script does entirely rely on the syntax of the clamav response text as well.
Old question but I've just had the same issue. clamdscan runs as user clamav which doesn't have permission to files in /tmp. There is an additional parameter --fdpass which runs the command as the user running the script.
Using $command = 'clamdscan --fdpass' . escapeshellarg($_FILES['file']['tmp_name']); should run the command as the www user which will have access to the temporary file.
I am trying to use PHP with word.application to read a file. It simply will not open the file. It's echoing the right version.
$w = new COM("word.application") or die("Is office installed?");
echo 'Loaded Word, version ' . $w->Version . '<br>';
$w->Visible = false;
$w->Documents->Open(realpath('test.docx'));
$content = (string) $w->ActiveDocument->Content;
echo $content;
$w->Quit();
$w->Release();
$w = null;
I get the error:
Uncaught exception 'com_exception' with message 'Source: Microsoft Word
Description: This command is not available because no document is open.'
It feels like it's some kind of permission problem. I tried to put the path of the test.docx besides using realpath and that did not help. Also tried to put it in the root of my C drive. I am using Windows 7 Professional and Microsoft Office 2007.
Documents->Open returns a document if all is ok. Probably, the document does not exists (path incorrect), or you haven't got the rights to open it from PHP. Store the result in $var, check if it has an appropriate value (probably not isset, null or false if not), and use $var->Content to read the content.
Try doing a file_exists on said
file/path.
If that works, try
file_get_contents and see if you can
read it.
If that all works - then it's not a problem with permissions/etc.
If the code is the same, there appears to be a difference between:
include 'external.php';
and
eval('?>' . file_get_contents('external.php') . '<?php');
What is the difference? Does anybody know?
I know the two are different because the include works fine and the eval gives an error. When I originally asked the question, I wasn't sure whether it gave an error on all code or just on mine (and because the code was evaled, it was very hard to find out what the error meant). However, after having researched the answer, it turns out that whether or not you get the error does not depend on the code in the external.php, but does depend on your php settings (short_open_tag to be precise).
After some more research I found out what was wrong myself. The problem is in the fact that <?php is a "short opening tag" and so will only work if short_open_tag is set to 1 (in php.ini or something to the same effect). The correct full tag is <?php, which has a space after the second p.
As such the proper equivalent of the include is:
eval('?>' . file_get_contents('external.php') . '<?php ');
Alternatively, you can leave the opening tag out all together (as noted in the comments below):
eval('?>' . file_get_contents('external.php'));
My original solution was to add a semicolon, which also works, but looks a lot less clean if you ask me:
eval('?>' . file_get_contents('external.php') . '<?php;');
AFAIK you can't take advantage of php accelerators if you use eval().
If you are using a webserver on which you have installed an opcode cache, like APC, eval will not be the "best solution" : eval'd code is not store in the opcode cache, if I remember correctly (and another answer said the same thing, btw).
A solution you could use, at least if the code is not often changed, is get a mix of code stored in database and included code :
when necessary, fetch the code from DB, and store it in a file on disk
include that file
as the code is now in a file, on disk, opcode cache will be able to cache it -- which is better for performances
and you will not need to make a request to the DB each time you have to execute the code.
I've worked with software that uses this solution (the on-disk file being no more than a cache of the code stored in DB), and I worked not too bad -- way better that doing loads of DB requests of each page, anyway...
Some not so good things, as a consequence :
you have to fetch the code from the DB to put it in the file "when necessary"
this could mean re-generating the temporary file once every hour, or deleting it when the entry in DB is modified ? Do you have a way to identify when this happens ?
you also have to change your code, to use the temporary file, or re-generate it if necessary
if you have several places to modifiy, this could mean some work
BTW : would I dare saying something like "eval is evil" ?
This lets you include a file assuming file wrappers for includes is on in PHP:
function stringToTempFileName($str)
{
if (version_compare(PHP_VERSION, '5.1.0', '>=') && strlen($str < (1024 * 512))) {
$file = 'data://text/plain;base64,' . base64_encode($str);
} else {
$file = Utils::tempFileName();
file_put_contents($file, $str);
}
return $file;
}
... Then include that 'file.' Yes, this will also disable opcode caches, but it makes this 'eval' the same as an include with respect to behavior.
As noted by #bwoebi in this answer to my question, the eval substitution does not respect the file path context of the included file. As a test case:
Baz.php:
<?php return __FILE__;
Foo.php:
<?php
echo eval('?>' . file_get_contents('Baz.php', FILE_USE_INCLUDE_PATH)) . "\n";
echo (include 'Baz.php') . "\n";
Result of executing php Foo.php:
$ php Foo.php
/path/to/file/Foo.php(2) : eval()'d code
/path/to/file/Baz.php
I don't know of any way to change the __FILE__ constant and friends at runtime, so I do not think there is any general way to define include in terms of eval.
Only eval('?>' . file_get_contents('external.php')); variant is correct replacement for include.
See tests:
<?php
$includes = array(
'some text',
'<?php print "some text"; ?>',
'<?php print "some text";',
'some text<?php',
'some text<?php ',
'some text<?php;',
'some text<?php ?>',
'<?php ?>some text',
);
$tempFile = tempnam('/tmp', 'test_');
print "\r\n" . "Include:" . "\r\n";
foreach ($includes as $include)
{
file_put_contents($tempFile, $include);
var_dump(include $tempFile);
}
unlink($tempFile);
print "\r\n" . "Eval 1:" . "\r\n";
foreach ($includes as $include)
var_dump(eval('?>' . $include . '<?php '));
print "\r\n" . "Eval 2:" . "\r\n";
foreach ($includes as $include)
var_dump(eval('?>' . $include));
print "\r\n" . "Eval 3:" . "\r\n";
foreach ($includes as $include)
var_dump(eval('?>' . $include . '<?php;'));
Output:
Include:
some textint(1)
some textint(1)
some textint(1)
some text<?phpint(1)
some textint(1)
some text<?php;int(1)
some textint(1)
some textint(1)
Eval 1:
some textNULL
some textNULL
bool(false)
some text<?phpNULL
bool(false)
some text<?php;NULL
some textNULL
some textNULL
Eval 2:
some textNULL
some textNULL
some textNULL
some text<?phpNULL
some textNULL
some text<?php;NULL
some textNULL
some textNULL
Eval 3:
some text<?php;NULL
some text<?php;NULL
bool(false)
some text<?php<?php;NULL
bool(false)
some text<?php;<?php;NULL
some text<?php;NULL
some text<?php;NULL
Some thoughts about the solutions above:
Temporary file
Don't. It's very bad for performance, just don't do it. Not only does it drive your opcode cache totally crazy (cache hit never happens + it tries to cache it again every time) but also gives you the headache of filesystem locking under high (even moderate) loads, as you have to write the file and Apache/PHP has to read it.
Simple eval()
Acceptable in rare cases; don't do it too often. Indeed it's not cached (poor opcode cache just doesn't know it's the same string as before); at the same time, if your code is changing each time, eval is A LOT BETTER than include(), mostly because include() fills up the opcode cache on each call. Just like the tempfile case. It's horrible (~4x slower).
In-memory eval()
Actually, eval is very fast when your script is already in the string; most of the time it's the disk operation that pulls it back, now surely this depends on what you do in the script but in my very-small-script case, it was ~400 times faster. (Do you have memcached? Just thinking loud) So what include() can't do is evaluate the same thing twice without file operation, and this is very important. If you use it for ever-changing, small, memory-generated strings, obviously it's eval to choose - it's many-many times faster to load once + eval again and again than an iterated include().
TL;DR
Same code, once per request: include
Same code, several calls per request: eval
Varying code: eval
here is my approach.
it creates temporary php file and includes it.
but this way if code you want to run on this function has errors program exits before removing temporary file
so i make an autoclean procedure in function. this way it cleans old temporary files by an timeout everytime function runs. you can set timeout or disable it from options at start of function
i also added ignore error option for solving non removed temporary files. if errors ignored, program will continue and remove temporary file.
also some projects have to disable autoclean because it scans whole directory everytime it runs. it could hurt disk performance.
function eval2($c) {
$auto_clean_old_temporary_files=false; //checks old temporary eval2 files for this spesific temporary file names generated by settings below
$ignore_all_errors=true; //if you ignore errors you can remove temporary files even there is an error
$tempfiledirectory=''; //temporary file directory
$tempfileheader='eval2_'; // temporary file header
$tempfiletimeseperator='__'; // temporary file seperator for time
$tempfileremovetimeout=200; // temp file cleaning time in seconds
if ($auto_clean_old_temporary_files===true) {
$sd=scandir('.'); //scaning for old temporary files
foreach ($sd as $sf) {
if (strlen($sf)>(32+strlen($tempfileheader)+strlen($tempfiletimeseperator)+3)) { // if filename long enough
$t1=substr($sf,(32+strlen($tempfileheader)),strlen($tempfiletimeseperator)); //searching time seperator
$t2=substr($sf,0,strlen($tempfileheader)); //searching file header
if ($t1==$tempfiletimeseperator && $t2==$tempfileheader) { //checking for timeseperator and file name header
$ef=explode('.',$sf);
unset($ef[count($ef)]);//removing file extension
$nsf=implode('.',$ef);//joining file name without extension
$ef=explode($tempfiletimeseperator,$nsf);
$tm=(int)end($ef); //getting time from filename
$tmf=time()-$tm;
if ($tmf>$tempfileremovetimeout && $tmf<123456 && $tmf>0) { // if time passed more then timeout and difference with real time is logical
unlink($sf); // finally removing temporary file
}
}
}
}
}
$n=$tempfiledirectory.$tempfileheader . md5(microtime().rand(0,5000)). $tempfiletimeseperator . time() .'.php'; //creating spesific temporary file name
$c='<?php' . PHP_EOL . $c . PHP_EOL; //generating php content
file_put_contents($n,$c); //creating temporary file
if ($ignore_all_errors===true) { // including temporary file by your choise
$s=#include($n);
}else{
$s=include($n);
}
return $s;
}