How do you restrict users to upload only pure html files - php

how can I restrict users to upload files that are Pure HTML Only.
I'm currently creating an online editor in PHP that would produce a web page which can be printed to PDF. As such, I have some HTML files that need to be dynamically included in the web page. This is because manually adding them through the online editor would take a long time as they include a lot of content, plus they contain static data which need not be changed. Think of them as presets.
Now the problem occurs when I let the users upload their own presets. As far as I know, any file with the .html extension can hold PHP code. How can I make sure that no PHP code lies within the uploaded file? Is it even possible to escape PHP tags using PHP?
Code example:
//User fills the PDF editor form and submits it.
is_logged(); // Login check and setting user info variables, redirects if not logged in.
if ( !isset( $_POST['gen-page'] ) {
custom_redirect( MAIN_PATH );
}
$content .= "<html>";
$content .= "<head>";
$content .= "<meta charset='utf-8'>";
$content .= "<meta name=viewport' content='width=device-width, initial-scale=1'>";
$content .= "<title>"$user_name"</title>";
$content .= file_get_contents( MAIN_PATH . '/uploads/' . $user_id . '/' . $user_style . '.html' ); // Contains style details.
$content .= "</head>";
$content .= "<body>";
for ($inputs as $input) { // Inputs is an array that was posted by the user.
$content .= "<p>" . $input . "</p>";
}
$content .= file_get_contents( MAIN_PATH . '/uploads/' . $user_id . '/' . $user_file . '.html' ); // The preset that the user has uploaded.
$content .= '</body>';
$filename = MAIN_PATH.'viewable/view-' . $user_id . '.html';
file_put_contents( $filename, $content );
custom_redirect( MAIN_PATH.'viewable/view-' . $user_id . '.html' );

Related

PHP image load function reads from the controller instead of domain/folder/to/image

Dear stackoverflow community,
Loading images from function works when I am in the indexAction (index of the controller, e.g gallery). When I want to load images from function while in a sublink of the main controller (e.g gallery/family) it doesn't load the images.
So when going to: domain.com/gallery everything is working.
When going to domain.com/gallery/family the images will be trying to find "domain.com/gallery/app/assets/image/gallery/family/" instead of "domain.com/app/assets/image/gallery/family/".
Image location is at "app/assets/image/gallery/family/" then running this function:
public function insertFamilyImages()
{
$directory = 'app/assets/image/gallery/family/';
$extension = '.jpg';
$html = '';
if ( file_exists($directory) ) {
foreach ( glob($directory . '*' . $extension) as $file ) {
$html .= '<li>';
$html .= '<img src="' . $file . '" alt="">';
$html .= '</li>';
}
} else {
echo 'directory ' . $directory . ' doesn\'t exist!';
}
return $html;
}
I am stuck at this and google doesn't help me. Neither I can find a similiar post on stackoverflow regarding this issue.
Thanks in advance,
Caleb
From looking at this it looks like when you create your html you point the img src to the file system path and not the uri. This html will be loaded in a remote browser and the browser can't access a remote file system. It needs an uri.
E.g.
Let say your domain name is example.com and en example image is called eg.png
Your image is located on your disk at app/assets/image/gallery/family/eg.png (relative).
However your images are accessible externally at https://example.com/gallery/family/eg.png.
You code would look something like this:
public function insertFamilyImages()
{
$directory = 'app/assets/image/gallery/family/';
$uri = 'https://example.com/gallery/family/';
$extension = '.jpg';
$html = '';
if ( file_exists($directory) ) {
foreach ( glob($directory . '*' . $extension) as $file ) {
$file = $uri.basename($file);
$html .= '<li>';
$html .= '<img src="' . $file . '" alt="">';
$html .= '</li>';
}
} else {
echo 'directory ' . $directory . ' doesn\'t exist!';
}
return $html;
}
You'll have to adjust this code to fit your case, but it should point you in the right direction where the problem lies. I used a complete uri here to point to the image to illustrate the point, but this could be made relative as well to the web root.
Never load / read / import any file with relative path. Otherwise your code will be faulty unpredictable.
Always use absolute path. In first php file like index.php which is entry point to your application define global root path like this:
define('ROOT', __DIR__);
then use ROOT as your constant at all files access/manipulation in your application.
$directory = ROOT.'/app/assets/image/gallery/family/';
You will never have problems with paths.

How do I convert a base64 string to a png image in PHP?

I am trying to create a PHP form that outputs a PDF (using mPDF) of all the values in the form after hitting submit. I have included jSignature which takes in an e-signature drawn by the user. The signature is then converted to an image and outputs the data URI string in a text area.
<div id="signature"></div><br/>
<input type='button' id='click' value='click'>
<textarea id='output' name="signature"></textarea><br/>
<!-- Preview image -->
<img src='' id='sign_prev' style='display: none;' />
<!-- Script -->
<script>
$(document).ready(function() {
// Initialize jSignature
var $sigdiv = $("#signature").jSignature({'UndoButton':true});
$('#click').click(function(){
// Get response of type image
var data = $sigdiv.jSignature('getData', 'image');
// Storing in textarea
$('#output').val(data);
// Alter image source
$('#sign_prev').attr('src',"data:"+data);
$('#sign_prev').show();
});
});
</script>
<button type="submit" class="btn btn-success btn-lg">Submit</button>
I have another file that uses the name attribute from the input areas to display the values from each input field to show on the PDF. Since the signature comes in as a data URI string I have to convert it back into a png image before creating the PDF. What I am sure of at the moment is that I am able to retrieve the data URI string and I am able to replace the "image/png;base64" string that comes with it so all I am left with is the data itself. But I am struggling to decode the URI back to an image and I am not sure about how I should display it back as an image.
<?php
require_once __DIR__ . '/vendor/autoload.php';
//grab variables
$inspection = $_POST['inspection'];
$ccOfficer = $_POST['cco-name'];
$inspector = $_POST['inspector'];
$tower = $_POST['tower'];
$strata = $_POST['strata'];
$suite = $_POST['suite'];
$phone = $_POST['phone'];
$email = $_POST['email'];
$signature = $_POST['signature'];
//Create new PDf instance
$mpdf = new \Mpdf\Mpdf();
$mpdf->debug = true;
$signature = str_replace('image/png;base64,','', $signature);
$signatureDecode = base64_decode($signature);
$im = imagecreatefromstring($signatureDecode);
if(!$im) {
die('Base64 value is not a valid image');
};
// $img_file = '/wti-report-form/images/signature.png';
// imagepng($im, $img_file, 0);
//$file = fopen($output_file, "wb");
//fwrite($file, $signatureDecode);
//fclose($file);
//Create our PDF
$data = '';
$data .= '<h1>ARC - NEW HOME WALK-THROUGH CHECKLIST</h1>';
//add data
$data .= '<strong>Inspection Date</strong> ' . $inspection . '<br/>';
$data .= '<strong>Customer Care Officer</strong> ' . $ccOfficer . '<br/>';
$data .= '<strong>This Suite was inspected by</strong> ' . $inspector . '<br/>';
$data .= '<strong>Tower #</strong> ' . $tower . '<br/>';
$data .= '<strong>Strata Lot #</strong> ' . $strata . '<br/>';
$data .= '<strong>Suite #</strong> ' . $suite . '<br/>';
$data .= '<strong>Email</strong> ' . $phone . '<br/>';
$data .= '<strong>Phone</strong> ' . $email . '<br/>';
//$data .= "<img src='" . $file . "'/>";
//$data .= '<p>' . $signature . '</p>';
//Write PDF
$mpdf->WriteHTML($data);
//output to the browser
$mpdf->Output('myfile.pdf', 'I');
?>
Any help will be appreciated. Thanks! :)
As far as I know You can use base64 data string in img tag and mpdf will render PDF correctly, did You try this solution ?
$data.='<img src="data:image/png;base64,'.$signature.'" />';

How do I extract from WordPress database to MS Excel?

I am trying to add data into excel file which is extracted from wordpress database, Actually I am trying to export data (tags) from database into excel file. And I write down a code, but when I click on generate button. This generates empty file.
Please guys check what I am doing wrong.
Codes are below:
if (check_admin_referer('tag-export'))
{
$blogname = str_replace(" ", "", get_option('blogname'));
$date = date("m-d-Y");
$xls_file_name = $blogname."-exported-tags-".$date;
$tags = get_terms( 'post_tag' , 'hide_empty=0' );
$count = count($tags);
if ( $count > 0 )
{
echo 'name' . "\t" . 'slug' . "\n";
foreach ( $tags as $tag )
{
echo $tag->name . "\t" . $tag->slug . "\n";
}
}
ob_clean();
echo $xls_file;
header( "Content-Type: application/vnd.ms-excel" );
header( "Content-disposition: attachment; filename=$xls_file_name.xls" );
exit();
}
The above codes are not writing data into excel file. please check and let me know.
Just based on your existing code:
if (check_admin_referer('tag-export'))
{
$blogname = str_replace(" ", "", get_option('blogname'));
$date = date("m-d-Y");
$xls_file_name = $blogname."-exported-tags-".$date;
$tags = get_terms( 'post_tag' , 'hide_empty=0' );
$count = count($tags);
$xls_file = '';
if ( $count > 0 )
{
$xls_file .= 'name' . "\t" . 'slug' . "\n";
foreach ( $tags as $tag )
{
$xls_file .= $tag->name . "\t" . $tag->slug . "\n";
}
}
ob_clean();
header( "Content-Type: application/vnd.ms-excel" );
header( "Content-disposition: attachment; filename=$xls_file_name.xls" );
echo $xls_file;
exit();
}
A more general suggestion, not a solution for your coding problem: create an HTML table file from the code and then open it in Excel for conversion. Doing it so you'll have a better understand on what's going on with your code: you can add var_dumps or simply debug it like a normal web page.
Having an html table is also useful because excel works quite well in converting it to XLS files.
After your HTML file works well, then you can apply necessary formatting/header to the code in order to create the xls file from scratch.

MediaWiki + Graphviz + Image maps + Pagelinks

Background: Working with MediaWiki 1.19.1, Graphviz 2.28.0, Extension:GraphViz 0.9 on WAMP stack (Server 2008, Apache 2.4.2, MySQL 5.5.27, PHP 5.4.5). Everything is working great and as expected for the basic functionality of rendering a clickable image from a Graphviz diagram using the GraphViz extension in MediaWiki.
Problem: The links in the image map are not added to the MediaWiki pagelinks table. I get why they aren't added but it becomes an issue if there is no way to follow the links back with the 'What links here' functionality.
Desired solution: During the processing of the diagram in the GraphViz extension, I would like to use the generated .map file to then create a list of wikilinks to add on the page to get picked up by MediaWiki and added to the pagelinks table.
Details:
This GraphViz extension code:
<graphviz border='frame' format='png'>
digraph example1 {
// define nodes
nodeHello [
label="I say Hello",
URL="Hello"
]
nodeWorld [
label="You say World!",
URL="World"
]
// link nodes
nodeHello -> nodeWorld!
}
</graphviz>
Generates this image:
And this image map code in a corresponding .map file on the server:
<map id="example1" name="example1">
<area shape="poly" id="node1" href="Hello" title="I say Hello" alt="" coords="164,29,161,22,151,15,137,10,118,7,97,5,77,7,58,10,43,15,34,22,31,29,34,37,43,43,58,49,77,52,97,53,118,52,137,49,151,43,161,37"/>
<area shape="poly" id="node2" href="World" title="You say World!" alt="" coords="190,125,186,118,172,111,152,106,126,103,97,101,69,103,43,106,22,111,9,118,5,125,9,133,22,139,43,145,69,148,97,149,126,148,152,145,172,139,186,133"/>
</map>
From that image map file, I would like to be able to extract the href and title to build wikilinks like so:
[[Hello|I say Hello]]
[[World|You say World!]]
I'm guessing that since that .map file is essentially XML that I could just use XPATH to query the file, but that is just a guess. PHP is not my strongest area and I don't know the best approach to going about the XML/XPATH option or if that is even the best approach to pull that info from the file.
Once I got that collection/array of wikilinks from the .map file, I'm sure I can hack up the GraphViz.php extension file to add it to the contents of the page to get it added to the pagelinks table.
Progress: I had a bit of an Rubber Duck Problem Solving moment right as I submitted the question. I realized that since I had well formed data in the image map, that XPATH was probably the way to go. It was fairly trivial to be able to pull the data I needed, especially since I found that the map file contents was stilled stored in a local string variable.
$xml = new SimpleXMLElement( $map );
foreach($xml->area as $item) {
$links .= "[[" . $item->attributes()->href . "|" . $item->attributes()->title . "]]";
}
Final Solution: See my accepted answer below.
Thanks for taking a look. I appreciate any assistance or direction you can offer.
I finally worked through all of the issues and now have a fairly decent solution to render the graph nicely, provide a list of links, and register the links with wiki. My solution doesn't fully support all of the capabilities of the current GraphViz extension as it is written as there is functionality we do not need and I do not want to support. Here are the assumptions / limitations of this solution:
Does not support MscGen: We only have a need for Graphviz.
Does not support imageAtrributes: We wanted to control the format and presentation and it seemed like there were inconsistencies in the imageAttributes implementation that would then cause further support issues.
Does not support wikilinks: While it would be nice to provide consistent link usage through wiki and the Graphviz extension, the reality is that Graphviz is a completely different markup environment. While the current extension 'supports' wikilinks, the implementation is a little weak and leaves areas for confusion. Example: Wikilinks support giving the link an optional description but Graphviz already uses the node label for the description. So then you end up ignoring the wikilink description and telling users that 'Yes, we support wikilinks but don't use the description part' So since we aren't really using wikilinks correctly, just implement a regular link implementation and try to avoid the confusion entirely.
Here is what the output looks like:
Here are the changes that were made
Comment out this line:
// We don't want to support wikilinks so don't replace them
//$timelinesrc = rewriteWikiUrls( $timelinesrc ); // if we use wiki-links we transform them to real urls
Replace this block of code:
// clean up map-name
$map = preg_replace( '#<ma(.*)>#', ' ', $map );
$map = str_replace( '</map>', '', $map );
if ( $renderer == 'mscgen' ) {
$mapbefore = $map;
$map = preg_replace( '/(\w+)\s([_:%#/\w]+)\s(\d+,\d+)\s(\d+,\d+)/',
'<area shape="$1" href="$2" title="$2" alt="$2" coords="$3,$4" />',
$map );
}
/* Procduce html
*/
if ( $wgGraphVizSettings->imageFormatting )
{
$txt = imageAtrributes( $args, $storagename, $map, $outputType, $wgUploadPath ); // if we want borders/position/...
} else {
$txt = '<map name="' . $storagename . '">' . $map . '</map>' .
'<img src="' . $wgUploadPath . '/graphviz/' . $storagename . '.' . $outputType . '"' .
' usemap="#' . $storagename . '" />';
}
With this code:
$intHtml = '';
$extHtml = '';
$badHtml = '';
// Wrap the map/area info with top level nodes and load into xml object
$xmlObj = new SimpleXMLElement( $map );
// What does map look like before we start working with it?
wfDebugLog( 'graphviz', 'map before: ' . $map . "\n" );
// loop through each of the <area> nodes
foreach($xmlObj->area as $areaNode) {
wfDebugLog( 'graphviz', "areaNode: " . $areaNode->asXML() . "\n" );
// Get the data from the XML attributes
$hrefValue = (string)$areaNode->attributes()->href;
$textValue = (string)$areaNode->attributes()->title;
wfDebugLog( 'graphviz', '$hrefValue before: ' . $hrefValue . "\n" );
wfDebugLog( 'graphviz', '$textValue before: ' . $textValue . "\n" );
// For the text fields, multiple spaces (" ") in the Graphviz source (label)
// turns into a regular space followed by encoded representations of
// non-breaking spaces ("   ") in the .map file which then turns
// into the following in the local variables: ("   ").
// The following two options appear to convert/decode the characters
// appropriately. Leaving the lines commented out for now, as we have
// not seen a graph in the wild with multiple spaces in the label -
// just happened to stumble on the scenario.
// See http://www.php.net/manual/en/simplexmlelement.asxml.php
// and http://stackoverflow.com/questions/2050723/how-can-i-preg-replace-special-character-like-pret-a-porter
//$textValue = iconv("UTF-8", "ASCII//TRANSLIT", $textValue);
//$textValue = html_entity_decode($textValue, ENT_NOQUOTES, 'UTF-8');
// Now we need to deal with the whitespace characters like tabs and newlines
// and also deal with them correctly to replace multiple occurences.
// Unfortunately, the \n and \t values in the variable aren't actually
// tab or newline characters but literal characters '\' + 't' or '\' + 'n'.
// So the normally recommended regex '/\s+/u' to replace the whitespace
// characters does not work.
// See http://stackoverflow.com/questions/6579636/preg-replace-n-in-string
$hrefValue = preg_replace("/( |\\\\n|\\\\t)+/", ' ', $hrefValue);
$textValue = preg_replace("/( |\\\\n|\\\\t)+/", ' ', $textValue);
// check to see if the url matches any of the
// allowed protocols for external links
if ( preg_match( '/^(?:' . wfUrlProtocols() . ')/', $hrefValue ) ) {
// external link
$parser->mOutput->addExternalLink( $hrefValue );
$extHtml .= Linker::makeExternalLink( $hrefValue, $textValue ) . ', ';
}
else {
$first = substr( $hrefValue, 0, 1 );
if ( $first == '\\' || $first == '[' || $first == '/' ) {
// potential UNC path, wikilink, absolute or relative path
$hrefValue = '#InvalidLink';
$badHtml .= Linker::makeExternalLink( $hrefValue, $textValue ) . ', ';
$textValue = 'Invalid link. Check Graphviz source.';
}
else {
$title = Title::newFromText( $hrefValue );
if ( is_null( $title ) ) {
// invalid link
$hrefValue = '#InvalidLink';
$badHtml .= Linker::makeExternalLink( $hrefValue, $textValue ) . ', ';
$textValue = 'Invalid link. Check Graphviz source.';
}
else {
// internal link
$parser->mOutput->addLink( $title );
$intHtml .= Linker::link( $title, $textValue ) . ', ';
$hrefValue = $title->getFullURL();
}
}
}
$areaNode->attributes()->href = $hrefValue;
$areaNode->attributes()->title = $textValue;
}
$map = $xmlObj->asXML();
// The contents of $map, which is now XML, gets embedded
// in the HTML sent to the browser so we need to strip
// the XML version tag and we also strip the <map> because
// it will get replaced with a new one with the correct name.
$map = str_replace( '<?xml version="1.0"?>', '', $map );
$map = preg_replace( '#<ma(.*)>#', ' ', $map );
$map = str_replace( '</map>', '', $map );
// Let's see what it looks like now that we are done with it.
wfDebugLog( 'graphviz', 'map after: ' . $map . "\n" );
$txt = '' .
'<table style="background-color:#f9f9f9;border:1px solid #ddd;">' .
'<tr>' .
'<td style="border:1px solid #ddd;text-align:center;">' .
'<map name="' . $storagename . '">' . $map . '</map>' .
'<img src="' . $wgUploadPath . '/graphviz/' . $storagename . '.' . $outputType . '"' . ' usemap="#' . $storagename . '" />' .
'</td>' .
'</tr>' .
'<tr>' .
'<td style="font:10px verdana;">' .
'This Graphviz diagram links to the following pages:' .
'<br /><strong>Internal</strong>: ' . ( $intHtml != '' ? rtrim( $intHtml, ' ,' ) : '<em>none</em>' ) .
'<br /><strong>External</strong>: ' . ( $extHtml != '' ? rtrim( $extHtml, ' ,' ) : '<em>none</em>' ) .
( $badHtml != '' ? '<br /><strong>Invalid</strong>: ' . rtrim($badHtml, ' ,') .
'<br /><em>Tip: Do not use wikilinks ([]), UNC paths (\\) or relative links (/) when creating links in Graphviz diagrams.</em>' : '' ) .
'</td>' .
'</tr>' .
'</table>';
Possible enhancements:
It would be nice if the list of links below the graph were sorted and de-duped.

php file put contents reverse

Ok sorry if its a stupid question im a begginer.
Im making a small shoutbox just for practise.
It inserts the shout infos in a txt file.
My problem is that, it lists the text from top to bottom, and i would like to do this reversed.
if(isset($_POST['submit'])) {
$text = $_POST['text'];
if(!empty($text)) {
$text = $_POST['text'];
$name = $_POST['name'];
$time = date("H:i");
$content =
"<div class='text'><em>" . $time . "</em>
<span class='c11'><b>" . "<a href='userinfo_php_willbe_here.php' target='_blank'>" . htmlspecialchars($name) . "</a>" . ":</span></b>
" . htmlspecialchars($text) . "
</div>\n";
file_put_contents($file, $content, FILE_APPEND | LOCK_EX);
}
}
here is my code.
i was googleing around with not much luck maybe i wasnt looking hard enough.
could please someone give me a hint?
thank you
No way to do so with one function call. You need to read the content from your target file, prepend the data in php and rewrite the whole file (see file_get_contents).
$fileContent = file_get_contents($file);
$fileContent = $content . $fileContent;
file_put_contents($file, $fileContent, LOCK_EX);
You can also use the array_reverse like so:
// Data in file separated by new-line
$data = explode("\n",file_get_contents("filename.txt"));
foreach(array_reverse($data) as $value) {
echo $value."\n";
}
You can only prepend to a file by means of reading it and writing afterwards.
file_put_contents($file, $content . file_get_contents($file), LOCK_EX);

Categories