简体   繁体   中英

Perl CGI script reads text file content with backslash incorrectly

I have a simple text file with lines containing backslash (\\something). When reading it in Perl scripts on the command line, I get the text lines exactly as they are in the file. When EXACT SAME lines of code are copied and pasted into a CGI script, the text file contents are read differently by adding one more backslash for each backslash. I spent two days on searching various forums (StackOverflow, PerlMonks, etc.) but could not find probable cause. Below is the code and text file. Any help is greatly appreciated.

**~/tests/backslash> cat /home/user1/tests/backslash/pattern.txt**
more LaTex formatted strings.
\frac{a}{b} = \frac{5}{7}
**~/tests/backslash>  cat test.pl**
my $file = "/home/user1/tests/backslash/pattern.txt";
print STDERR "Attempting to open $file and read the last line...\n";
open(FH, "< $file") or die "ERROR: can't open $file: $!";
my @lines = <FH>;
close(FH);
my $myExpression = $lines[scalar(@lines) - 1];
chomp($myExpression);
print STDERR 'Expr: [' . $myExpression . "]\n";
my $retString = qq{{ "result" : "$myExpression" }};
print STDERR $retString . "\n";
**~/tests/backslash> ./test.pl**
Attempting to open /home/user1/tests/backslash/pattern.txt and read the last line...
Expr: [\frac{a}{b} = \frac{5}{7}]
{ "result" : "\frac{a}{b} = \frac{5}{7}" }
**~/tests/backslash>**

This exact same code in CGI script produces the following output:

CGI 脚本的输出 I split the string into array and examined each character (in the CGI script), which has two backslashes before 'frac'. Dumper confirms this as well. I tried to substitute two backslashes with '\\' but was not successful with that either. I hit so many other problems in understanding and fixing this problem (eg. CGI script could not open the same text file from /tmp[file not found], substituting two backslashes with \\ in various ways failed with syntax errors, variable values are getting unexpected characters when substituting, etc. but I am focusing on the core problem of backslashes in this question.) I made all the 'use' classes exactly the same in the command line script and CGI script just in case, even though command line script does not use CGI, JSON, etc.

I am perplexed why exact same Perl code behaves differently in cgi-bin. Any help, suggestion, pointers, or discussion on this is appreciated.

My environment:
Suse Linux 13.1
Perl 5.18.1
Apache 2.4.6
Bash 4.2.53

Please see if following coding style will be more appropriate

use strict;
use warnings;
use feature 'say';

my $file = '/home/user1/tests/backslash/pattern.txt';

say STDERR "Attempting to open $file and read the last line...";

open my $fh, '<',  $file
    or die "ERROR: can't open $file: $!";

my @lines = <$fh>;

close(FH);

my $myExpression = pop @lines;

chomp($myExpression);

say STDERR "Expr: [$myExpression]";

my $retString = qq{{ "result" : "$myExpression" }};

say STDERR $retString;

NOTE: perl has operator pop to extract last element of an array

NOTE: double quoted string assumes variable interpolation and it should be used accordingly -- if no variable in the string then probably double quotes are misplaced

NOTE: free book Modern Perl is available online -- see 'Input and Output' page 138

NOTE: use strict; use warnings use strict; use warnings allows to avoid many pitfalls

I think I figured out where the problem is. It was in MathJax where it takes the LaTex string and renders. It kept rendering the string with backslashes, so I traced back where the double backslashes are coming from and ended up finding them in the http logs. Any printing to the files also resulted in escaping. The script when ran on the command line prints it to the terminal, so the backslashes are not escaped. When running in the cgi-bin, there is no way to see the actual string without escaping. Splitting the string into array and printing the characters individually makes no difference. Comparison of the array elements to quoted q|\\|also subject to escaping/interpolation. Therefore, I could not validate this in any other way. Finally, after fixing the configuration of MathJax, it rendered the string correctly. I am leaving this question and answer hoping it saves sometime for somebody. Thank you all for reading, commenting, and answering.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM