Syntax for # literal in ms-access hyperlink? - ms-access

This seems like it ought to be a trivial question, but I'm having a hell of a time finding an answer for this so far...
I have an access database that stores hyperlinks to files on a shared network drive. The link targets are specified as simple file paths (e.g. "G:\directoryname\filename.ext") rather than proper URL's ("http://domain.ext/link").
This works fine in general, but I've recently run into a problem involving file names that contain the "#" character. (It is not an option to change the file names to remove the # characters)
If I try to set up a link to something like "G:\directoryname\ExampleFile#24.pdf", then Access parses the # in the filename as it would generally do when it defines a hyperlink. The resulting target is just ""G:\directoryname\ExampleFile", with the portion of the link following the offending "#" simply being truncated.
Now, obviously if the link target were a regular URL, I would just replace the "#" in the text of the link with "%23" and there would be no issue.
The problem is that, if I do that here, my network file action fails, because unlike when opening a regular URL through a browser, the network doesn't recognize %23 as equivalent to # ( I get an error saying "Unable to open G:\directoryname\ExampleFile %23 24.pdf. Cannot open the specified file.")
Is there a more direct way to have ms-access record the link target with a literal # character included?

Well this certainly doesn't help you but here is your answer:
"You cannot use a pound character in a file name for a hyperlink in an Office program"
https://support.microsoft.com/en-us/kb/202261

Related

HTML: how to use a href to link to a file name that starts with # character

I have many text files, the name of which starts with # (hash) sign. It would be very cumbersome to rename the files.
If I try to link to the text files in an HTML file, using <a href="#example.txt"> the browser interprets the leading # character as a "fragment identifier".
My requirement is for the link to open the text file in the browser.
I have tried substituting the leading # character like this:
<a href="#35;example.txt">
<a href="#&23;example.txt">
but that does not work (the text file is not opened).
Is there an HTML work-around, or is JavaScript required for this?
If you really need to do it you can try with replacing "#" with %23. It should work.
You will avoid lots and lots and lots of pain if you are able to rename your files so they don't contain a "#" character.
As long as they do, you will probably have current and future cross-browser issues, confusion on behalf of future developers working on your code (or confusion on your behalf in the future, when you've forgotten the ins and outs of the encoding), etc.
Also, some Unix/Linux systems don't allow "#" in filenames. Not sure what OS you're using, but your filenames should be as portable as possible across OSs, even if you're "sure" right now that you'll never be running on one of those systems.
Problem -
href with a # in front of the file name fails to load the file. This is because you need to URL Encode the symbol.
Solution -
Use %23 which is the URL Encoding for #.
Example -
If you want to use an href to link a file named #test.html, you would do this -
Click Me!
Recommendation -
Do not use file names with # in the name.
If you want to rename all of the files in the directory you are working in, here is a bash script that will do that for you.
#!/bin/bash
target="/home/user/directory/change/$1"
for f in "$target"/*
do
letter=$(basename $f | cut -c1-1)
if [ "$letter" == "#" ]; then
withoutHash=$(basename $f | cut -c 2-)
mv $f $withoutHash
fi
done
This bash script should be easy to understand but there is surely some one liner on Stack Overflow. Try setting up a test directory and playing with it. You could pretty easily figure out how to traverse sub directories if needed.
You have to remove the # in your fileNames. # means an id and the browser thinks its an id and looks for it on the page.

Chrome on Windows adding trailing underscores to downloaded files?

I've got a rather odd situation happening, that I'm having difficulty tracking down in an existing Django application. One of the views, which inherits from APIView, returns with a file when a user makes a POST call. The endpoint works fine, but there's something odd happening when the downloaded file reaches the client machine. By the time the browser receives the file, the file extension has been renamed with a trailing underscore. (So suppose the file was originally "test.txt", the version that the client receives would be "test.txt_").
As near as I can figure, just before the response object is returned in the APIView, the content-type and content-disposition headers look correct. E.g.:
Content-Type: application/octet-stream
Content-Disposition: attachment;filename="test.txt"
That same file, when it shows up in Chrome downloads, is named "test.txt_" - with the trailing underscore. I've tried the same thing out in Firefox, and it seems to download correctly. Unfortunately, telling the majority of our users to switch browsers isn't going to fly.
I have tried:
Forcing a different content type (e.g.: instead of "application/octet-stream", try "application/text", just to see what happens). This had no effect.
Formatting the content disposition slightly different (e.g.: space between the semicolon and filename). This also had no effect.
Removed the double quotes around the filename in the content-disposition header. No effect.
Dropping breakpoints within the Rest Framework itself, but Visual Studio Code doesn't seem to trigger on these. (I'm not super-familiar with debugging through Visual Studio Code, so this may be my fault).
Stripped out any custom middleware, so the only remaining middleware are as follows:
corsheaders.middleware.CorsMiddleware
django.contrib.sessions.middleware.SessionMiddleware
django.middleware.locale.LocaleMiddleware
django.middleware.common.CommonMiddleware
django.middleware.csrf.CsrfViewMiddleware
django.contrib.auth.middleware.AuthenticationMiddleware
django.contrib.messages.middleware.MessageMiddleware
So far, any similar issues that other people have experienced seem to be slightly different (i.e.: Internet Explorer removing the period in the extension and replacing it with an underscore).
Any guesses on what might be happening here? I'm a bit stumped.
You have to remove "" from your file name
Change attachment; filename="filename.txt" to attachment; filename=filename.txt
Although seems like you won't be able to have spacing in file name
I finally figured out what was going on here. The UI that was used to trigger the download was doing so through creating a temporary anchor tag (see the second answer here: Download data url file ). When it was doing so, it had two different cases. In one case, if downloading multiple files, it would change the file extension to .zip. In another case, if downloading a single file, it was still trying to append an extension, but the way the UI code was written, it was setting the extension to be an empty string. So the end result is a period being added, but no extension after that. For example, if the file being downloaded was "test.txt", it would end up as "test.txt.", which was then converted by Chrome to "test.txt_", on Windows, to make it a valid file extension.
Our environment has a document storage system that contains documents with the attributes DocumentName and ContentType. In some cases, the content type would return with spaces appended to the end of the string like "pdf ".
In Internet Explorer the output would truncate the end of the string while Chrome would convert the extra spaces to underscores giving me this filename: "file.pdf______________"
To resolve I simply truncate the string.
public string getFileName(string docName, string contentType) {
string fileName = docName + "." + contentType.Trim();
return fileName;
}
I encountered the same problem.
Let's say your download file name is "my_report.csv"
Then before doing the download operations get rid of " characters
fileName = fileName.replace('"','') // replacing one " charcter
fileName = fileName.replace('"','') // replacing second " character
This will resolve your issue.
My solution in ASP.NET core
[HttpGet("pdf/{fileId}")]
public IActionResult GetPdfFile([FromRoute]int fileId)
{
var result = Repo.GetFile(fileId);
Response.Headers.Add("Content-Disposition", $"inline; filename={result.FileName}");
return File(result.Data, "application/pdf");
}
I resolved this issue with replace white space in file name by a character like -.
This was happening for me when the filename included a comma.
lastname,MD.pdf
browser would download filestream as
_lastname,MD.pdf_
Adding code to remove a potential comma from the filename resolved the issue and made it download as expected.
filename = filename.Replace(",", ""); // replace comma characters with blank
now downloads as
lastnameMD.pdf
In my case there was a space as a first character, and it was replaced to underscore. So I simply removed the space :-)

app-assignment for vifm on windows

I'm on Win 10 and want to get rid of the Windows-Explorer and use mostly my keyboard with vifm.
But I have problems assigning a file extension to a specific app. Everything I want to open is opened with the built-in vim, instead of my external Apps.
Here is an Example from my config:
" Pdf
filextype *.pdf
\ {View in AR}
\ C:\Program Files (x86)\Adobe\Acrobat Reader DC\Reader\AcroRd32.exe %f
I have two Questions right now:
- Is there really no 'Open-With'-function in vifm? Can't believe....
- How do I correctly assign the file types in my win-environment?
Thanks 4 your support!!
There are two things that you need to fix with the command:
Escape spaces in path by enclosing it in quotes (vifm checks if programs are present and thus needs to be able to extract executable path from command-line).
Use Windows-friendly macro %"f instead of %f.
This will give you:
" Pdf
filextype *.pdf
\ {View in AR}
\ "C:\Program Files (x86)\Adobe\Acrobat Reader DC\Reader\AcroRd32.exe" %"f
Which should work.
Is there really no 'Open-With'-function in vifm?
Depends on what you mean. There is :file command, which will display
list of registered file associations. If you just want to go with those registered
in Windows, then use catch-all association filetype * start. If you're talking
about "Open with" menu like in Explorer, then no, such querying of registered
associations is not performed.
Late answer, but Xaizek's solution contains a few inaccuracies and isn't complete, since it is possible to get the open with dialogue if you're willing to jump through a tiny hoop:
To open pdf files by default with AcroRd32 you should add the following lines to your vifmrc:
filextype *.pdf
\ {View in AR}
\ "C:/Program Files (x86)/Adobe/Acrobat Reader DC/Reader/AcroRd32.exe" %"f &,
Note the forward slashes. Without these the command won't work. It's also generally a good idea to add &, at the end of any filextype line. This will allow acrord32 to open in the background and won't interrupt your vifm session; otherwise you'll have to close the pdf to continue using vifm.
On the second point, 'start' requires empty double quotes after it to work here:
filextype *.pdf
\ {View in default application}
\ start "" %"c &,
An alternative is to use explorer in place of start "". It's worth noting that this will only allow you to open one file a time instead of batch opening every selected pdf.
You can also open any file in a specific program via the shell, e.g. :!gvim %"c & will open the currently selected file in gvim. You may also replace %"c with any file name you want in the current directory.
Finally, you can get an open with dialogue for any selected file via the following method:
Create the file, ow.cmd, in your vifm directory (or any other location in your path) with the following contents:
Rundll32.exe shell32.dll,OpenAs_RunDLL %~1
Then add the following to your vifmrc:
" Create 'open with' dialogue box for selected file
nnoremap go :!ow.cmd %"c:p &<cr>
Now if you hit go within vifm it will bring up an 'open with' dialogue for the currently selected file. The external script is sadly necessary in order to remove the quotes from the file name that %"c:p tacks on.

Software error while executing CGI script

I have a cgi script for upload which is as follows
#!/usr/bin/perl
use CGI;
use CGI::Carp qw(fatalsToBrowser);
my $cgi = new CGI;
my $file = $cgi->param('file');
$file=~m/^.*(\\|\/)(.*)/; # strip the remote path and keep the filename
my $name = $2;
open(LOCAL, ">/home/Desktop/$name") or die $!;
while(<$file>) {
$data .= $_;
}
print $cgi->header();
print "$file has been successfully uploaded... thank you.\n";
print $data;
The HTML file is as follows
<html>
<head>
<title>Test</title>
</head>
<body>
<form enctype="multipart/form-data" action="upload.cgi" method="post">
<input type="hidden" name="MAX_FILE_SIZE" value="30000" />
Send this file: <input name="userfile" type="file" />
<input type="submit" value="Send File" />
</form>
</body>
</html>
I am getting a weird error now..
Software error:
Is a directory at htdocs/upload.cgi line 9.
For help, please send mail to this site's webmaster, giving this error message and the time and date of the error.
TL;DR
Stop. Shelve your script right now. It is a gaping security hole just waiting to be exploited. Read the following resources:
perlsec
the CERT Perl Secure Coding Standard
(particularly the section on Input Validation and Data Sanitization)
the OWASP page on Unrestricted File Upload
the InfoSec page on Complete File Upload Vulnerabilities
the CWE page on Unrestricted Upload of File with Dangerous Type
the SANS recommendations for 8 Basic Rules to Implement Secure File Uploads.
When you have read--and understood--all of them, stop and think if you really need to let users upload files onto your server. Think long and hard. Can you really account for all of the listed vulnerabilities? If you still feel like you need to do this, consider enlisting the help of a security expert. Follow the guidelines laid out in the above resources carefully and understand that a mistake in your design could compromise your entire site.
I understand that this is just a test script, not a production application (at least, I really hope that's the case), but even so, what you are doing (and particularly how you are doing it) is a very, very bad idea. Here are a select few of
the reasons why, from OWASP's page on Unrestricted File
Upload:
The website can be defaced.
The web server can be compromised by uploading and executing a web-shell which can: run a command, browse the system files, browse the local resources, attack to other servers, and exploit the local vulnerabilities, and so on.
This vulnerability can make the website vulnerable to some other types of attacks such as XSS.
Local file inclusion vulnerabilities can be exploited by uploading a malicious file into the server.
More from OWASP:
Uploaded files represent a significant risk to applications. The first step in
many attacks is to get some code to the system to be attacked. Then the attack
only needs to find a way to get the code executed. Using a file upload helps
the attacker accomplish the first step.
The consequences of unrestricted file upload can vary, including complete
system takeover, an overloaded file system, forwarding attacks to backend
systems, and simple defacement.
Pretty scary stuff, huh?
The problems
Your code
Let's start by looking at some of the problems with the code you posted.
No strict, no warnings
Start putting use strict; use warnings; at the top of every Perl script you
ever write. I recently had the pleasure of fixing a CGI script that contained
a snippet something like this:
my ($match) = grep { /$usrname/ } #users;
This code was used to check that the username entered in an HTML form matched a
list of valid users. One problem: the variable $usrname was
misspelled (it should have been $username with an 'e'). Since strict
checking was off, Perl happily inserted the value of the (undeclared) global
variable $usrname, or undef. That turned the innocent-looking snippet into this monstrosity:
my ($match) = grep { // } #users;
which matches everything in the valid users list and returns the first
match. You could enter anything you wanted into the username field in the form
and the script would think you were a valid user. Since warnings were also off,
this was never caught during the development process. When you turn warnings on,
the script will still run and return a user, but you also get something like
this:
Name "main::usrname" used only once: possible typo at -e line 1.
Use of uninitialized value $usrname in regexp compilation at -e line 1.
When you also turn on strict, the script fails to compile and won't even run at
all. There are other problems with this snippet (for example, the string 'a' will match the username 'janedoe'), but strict and warnings at least alerted us to one major issue. I cannot stress this enough: always, always use strict; use
warnings;
No taint mode
The first rule of web development is,
"Always sanitize user input." Repeat after me: Always sanitize user input. One more time: Always sanitize user input.
In other words, never
blindly trust user input without validating it first. Users (even those that are not malicious) are very good at entering creative values into form
fields that can break your application (or worse). If you don't restrict their creativity,
there is no limit to the damage a malicious user can do to your site (refer to the perennial #1
vulnerability on the OWASP Top 10,
injection).
Perl's taint mode can help with this. Taint mode forces you
to check all user input before using it in certain potentially dangerous operations like the
system() function. Taint mode is like the safety on a gun: it can prevent a lot of painful
accidents (although if you really want to shoot yourself in the foot, you can
always turn off the safety, like when you untaint a variable without actually removing dangerous characters).
Turn on taint mode in every CGI script you ever write. You can enable it by passing the -T flag, like this:
#!/usr/bin/perl -T
Once taint mode is enabled, your script will throw a fatal error if you try to
use tainted data in dangerous situations. Here's an example of such a dangerous situation that I found in a random script on the internet:
open(LOCAL, ">/home/Desktop/$name") or die $!;
Ok, I lied, that snippet isn't from a random script, it's from your code. In isolation, this snippet is just begging to be hit with a directory traversal attack, where a malicious user enters a relative path in order to access a file that they shouldn't have access to.
Fortunately, you've done something right here: you ensured that $name will contain no directory separators by using a regex*. This is exactly what taint mode would require you to do. The benefit of taint mode is that if you forget to sanitize your input, you will be alerted immediately with an error like this:
Insecure dependency in open while running with -T switch at foo.cgi line 5
Like strict, taint mode forces you to address problems in your code immediately by causing the program to fail, instead of allowing it to quietly limp along.
* You did something right, but you also did some things wrong:
Your program will die if the user passes in only a filename with no directory separators, e.g. foo
You don't remove special characters that could be interpreted by a shell, like |
You never sanitize the variable $file and yet you try to use it to read a file later in your code
You don't check if the file you're writing to already exists (see "No check for file existence" below)
You allow the user to choose the name of the file that will be stored on your server, which gives them far more control than you should be comfortable with (see "Allowing the user to set the file name" below)
CGI::Carp fatalsToBrowser
I'll give you the benefit of the doubt on this one since you're still testing your script, but just in case you weren't aware and since I'm already talking about CGI security issues, never enable CGI::Carp's fatalsToBrowser option in a production environment. It can reveal intimate details about the inner workings of your script to attackers.
Two-argument open() and global filehandles
Two-argument open(), e.g.
open FH, ">$file"
has a host of security risks associated with it when users are allowed to specify the file path. Your script mitigates many of these by using a hard-coded directory prefix, but that in no way diminishes the fact that using two-argument open can be very dangerous. In general, you should use the three-argument form:
open my $fh, ">", $file
(which is still plenty dangerous if you allow the user to specify the file name; see "Allowing the user to set the file name" below).
Also note that instead of the global filehandle FH I switched to a lexical filehandle $fh. See CERT's page Do not use bareword filehandles for some reasons why.
No check for file existence
You don't check whether a file already exists at /home/Desktop/$name when you open it for writing. If the file already exists, you will truncate it (erase its contents) as soon as the open() call succeeds, even if you never write anything to the file. Users (malicious and otherwise) are likely to clobber each other's files, which doesn't make for a very happy user base.
No limit on file size
"But wait," you say, "I set MAX_FILE_SIZE in my HTML form!" Understand that this is merely a suggestion to the browser; attackers can easily edit HTTP requests to remove this condition. Never rely on hidden HTML fields for security. Hidden fields are plainly visible in the HTML source of your page and in the raw HTTP requests. You must limit the maximum request size on the server side to prevent users from loading massive files to your server and to help alleviate one type of denial of service attack. Set the $CGI::POST_MAX variable at the beginning of your CGI script like this:
$CGI::POST_MAX=1024 * 30; # 30KB
Or even better, find CGI.pm on your system and change the value of $POST_MAX to set it globally for all scripts that use the CGI module. That way you don't have to remember to set the variable at the beginning of every CGI script you write.
CGI doesn't match the HTML form
The POST variable you use for the file path in your HTML form, userfile, does not match the variable you look for in your CGI script, file. This is why your script is failing with the error
Is a directory
The value of
$cgi->param('file')
is undef so your script tries to open the path
/home/Desktop/
as a regular file.
Obsolete method for handling upload
You are using the old (and obsolete) method of handling uploads with CGI.pm where param() is used to get both the file name and a lightweight filehandle. This will not work with strict and is insecure. The upload() method was added in v2.47 (all the way back in 1999!) as a preferred replacement. Use it like this (straight out of the documentation for CGI.pm):
$lightweight_fh = $q->upload('field_name');
# undef may be returned if it's not a valid file handle
if (defined $lightweight_fh) {
# Upgrade the handle to one compatible with IO::Handle:
my $io_handle = $lightweight_fh->handle;
open (OUTFILE,'>>','/usr/local/web/users/feedback');
while ($bytesread = $io_handle->read($buffer,1024)) {
print OUTFILE $buffer;
}
}
where field_name is the name of the POST variable that holds the file name (in your case, userfile). Notice that the sample code does not set the output filename based on user input, which leads to my next point.
Allowing the user to set the file name
Never allow users to choose the file name that will be used on your server. If an attacker can upload a malicious file to a known location, it becomes significantly easier for them to exploit. Instead, generate a new, unique (to prevent clobbering), difficult-to-guess file name, preferably in a path outside your web root so users cannot access them directly with a URL.
Other issues
You haven't even begun to address the following issues.
Authentication
Who is allowed to upload files using your web app? How will you ensure that only authorized users are uploading files?
Access control
Are users allowed to see the files uploaded by other users? Depending on the file content, there could be major privacy issues at stake.
Number and rate of uploads
How many files is one user allowed to upload? How many files is a user allowed to upload in a fixed period of time? If you don't restrict these, one user could easily eat up all of your server resources very quickly, even if you enforce a maximum file size.
Dangerous file types
How will you check that users are not uploading dangerous content (for example, executable PHP code) to your server? Simply checking the file extension or content type header is not enough; attackers have found some very creative methods for circumventing such checks.
"But, but, I'm only running this on my corporate intranet..."
You may be tempted to disregard these security issues if your script is not accessible from the internet. However, you still need to consider
In-office pranksters
Disgruntled coworkers
Collaborators and outside contractors who either need access to your app or who shouldn't have access
Managers who love your app so much that they decide to open it up to users on the internet without your knowledge, possibly after you've transferred to another group or left the company
"What should I do?"
Scrap your existing code. Read the resources I listed in the first paragraph, carefully. Here they are again:
perlsec
the CERT Perl Secure Coding Standard (particularly the section on Input Validation and Data
Sanitization)
OWASP's Unrestricted File Upload
InfoSec's Complete File Upload Vulnerabilities
CWE's Unrestricted Upload of File with Dangerous Type
SANS recommendations for 8 Basic Rules to Implement Secure File Uploads
Consider carefully if you really need to do this. If you just need to give users a place to store files, consider using (S)FTP instead. This would certainly not eliminate all of the security risks, but it would eliminate a big one: your custom CGI code.
If after careful consideration you still think this is necessary, work through some recent Perl tutorials to make sure you can use and understand modern Perl programming conventions. Instead of CGI.pm, use a framework like Catalyst, Dancer, or Mojolicious, all of which have plugins that can handle tricky areas like user authentication and sessions so you don't have to re-invent the wheel (poorly).
Follow all of the security guidelines listed in the above resources and consider enlisting the help of an expert in web security. Tread carefully: a single mistake in your code could allow an attacker to compromise your entire site and possibly even other machines on your network. Depending on what country your company and your users are in, this could even have legal ramifications.
</soapbox>
A few suggestions that might get you closer to a solution.
use strict and use warnings (always use these).
CGI->new() instead of new CGI (not essential, but a good habit to get into).
Your file upload form input is called "userfile", but in your CGI code you call it "file". That inconsistency needs to be fixed.
You get the filename with $cgi->param('file'), that gets you the filename correctly (well, once you've fixed the error in my previous point), but you later try to treat that filename as a file handle (while (<$file>)). That's not going to work.
You should probably read the documentation about how to process a file upload field using CGI.pm.

Passing parameters to a DOS batch file called from HTML

I have one question about executing a batch file which is linked via an HREF from a HTML page.
Till now I have the link to the batch file and it's executed without problems if I click on the link
> Call dos batch
This works fine.
Now I want to extend this to:
> Call dos batch with para
With this string, I get the error "The page cannot be displayed"
I allready tried several combinations with %22, %20, single quotes, double quotes and so on, but with no success
Has any one a hint for me ?
Thanks in advance,
Zirod
Links in HTML trigger your browser to fetch a file, and either render it if necessary (HTML, SVG, images, etc.) or prompt for a download for anything else. Links in HTML are not like a shell; you can't pass shell arguments to a file assuming it will be executed.