⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ch07_03.htm

📁 By Tom Christiansen and Nathan Torkington ISBN 1-56592-243-3 First Edition, published August 1998
💻 HTM
字号:
<HTML><HEAD><TITLE>Recipe 7.2. Opening Files with Unusual Filenames (Perl Cookbook)</TITLE><METANAME="DC.title"CONTENT="Perl Cookbook"><METANAME="DC.creator"CONTENT="Tom Christiansen &amp; Nathan Torkington"><METANAME="DC.publisher"CONTENT="O'Reilly &amp; Associates, Inc."><METANAME="DC.date"CONTENT="1999-07-02T01:36:03Z"><METANAME="DC.type"CONTENT="Text.Monograph"><METANAME="DC.format"CONTENT="text/html"SCHEME="MIME"><METANAME="DC.source"CONTENT="1-56592-243-3"SCHEME="ISBN"><METANAME="DC.language"CONTENT="en-US"><METANAME="generator"CONTENT="Jade 1.1/O'Reilly DocBook 3.0 to HTML 4.0"><LINKREV="made"HREF="mailto:online-books@oreilly.com"TITLE="Online Books Comments"><LINKREL="up"HREF="ch07_01.htm"TITLE="7. File Access"><LINKREL="prev"HREF="ch07_02.htm"TITLE="7.1. Opening a File"><LINKREL="next"HREF="ch07_04.htm"TITLE="7.3. Expanding Tildes in Filenames"></HEAD><BODYBGCOLOR="#FFFFFF"><img alt="Book Home" border="0" src="gifs/smbanner.gif" usemap="#banner-map" /><map name="banner-map"><area shape="rect" coords="1,-2,616,66" href="index.htm" alt="Perl Cookbook"><area shape="rect" coords="629,-11,726,25" href="jobjects/fsearch.htm" alt="Search this book" /></map><div class="navbar"><p><TABLEWIDTH="684"BORDER="0"CELLSPACING="0"CELLPADDING="0"><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="228"><ACLASS="sect1"HREF="ch07_02.htm"TITLE="7.1. Opening a File"><IMGSRC="../gifs/txtpreva.gif"ALT="Previous: 7.1. Opening a File"BORDER="0"></A></TD><TDALIGN="CENTER"VALIGN="TOP"WIDTH="228"><B><FONTFACE="ARIEL,HELVETICA,HELV,SANSERIF"SIZE="-1"><ACLASS="chapter"REL="up"HREF="ch07_01.htm"TITLE="7. File Access"></A></FONT></B></TD><TDALIGN="RIGHT"VALIGN="TOP"WIDTH="228"><ACLASS="sect1"HREF="ch07_04.htm"TITLE="7.3. Expanding Tildes in Filenames"><IMGSRC="../gifs/txtnexta.gif"ALT="Next: 7.3. Expanding Tildes in Filenames"BORDER="0"></A></TD></TR></TABLE></DIV><DIVCLASS="sect1"><H2CLASS="sect1"><ACLASS="title"NAME="ch07-17895">7.2. Opening Files with Unusual Filenames</A></H2><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch07-pgfId-382">Problem<ACLASS="indexterm"NAME="ch07-idx-1000009593-0"></A></A></H3><PCLASS="para">You want to open a file with a funny filename, like <CODECLASS="literal">&quot;-&quot;</CODE> or one that starts with &lt;, &gt;, or <CODECLASS="literal">|</CODE>, has leading or trailing whitespace; or ends with <CODECLASS="literal">|</CODE>. You don't want these to trigger <CODECLASS="literal">open</CODE>'s do-what-I-mean behavior, since in this case, that's <EMCLASS="emphasis">not</EM> what you mean.</P></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch07-pgfId-388">Solution</A></H3><PCLASS="para">Use <CODECLASS="literal">open</CODE> like this: <ACLASS="indexterm"NAME="ch07-idx-1000009592-0"></A><ACLASS="indexterm"NAME="ch07-idx-1000009592-1"></A></P><PRECLASS="programlisting">$filename =~ s#^(\s)#./$1#;open(HANDLE, &quot;&lt; $filename\0&quot;)          or die &quot;cannot open $filename : $!\n&quot;;</PRE><PCLASS="para">Or simply use <CODECLASS="literal">sysopen</CODE>:</P><PRECLASS="programlisting">sysopen(HANDLE, $filename, O_RDONLY)   or die &quot;cannot open $filename: $!\n&quot;;</PRE></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch07-pgfId-402">Discussion</A></H3><PCLASS="para">The <CODECLASS="literal">open</CODE> function uses a single string to determine both the filename and the mode &nbsp;-  the way the file is to be opened. If your filename begins with the characters used to indicate the mode, <CODECLASS="literal">open</CODE> can easily do something unexpected. Imagine the following code:</P><PRECLASS="programlisting">$filename = shift @ARGV;open(INPUT, $filename)               or die &quot;Couldn't open $filename : $!\n&quot;;</PRE><PCLASS="para">If the user gave <CODECLASS="literal">&quot;&gt;/etc/passwd&quot;</CODE> as the filename on the command line, this code would attempt to open <EMCLASS="emphasis">/etc/passwd</EM> for writing &nbsp;-  definitely unsafe! We can try to give an explicit mode, say for writing:</P><PRECLASS="programlisting">open(OUTPUT, &quot;&gt;$filename&quot;)    or die &quot;Couldn't open $filename for writing: $!\n&quot;;</PRE><PCLASS="para">but even this would let the user give a filename of <CODECLASS="literal">&quot;</CODE>&gt;<CODECLASS="literal">data&quot;</CODE> and the code would append to the file <CODECLASS="literal">data</CODE> instead of erasing the old contents.</P><PCLASS="para">The easiest solution is <CODECLASS="literal">sysopen</CODE>, which takes the mode and filename as separate arguments:</P><PRECLASS="programlisting">use Fcntl;                          # for file constantssysopen(OUTPUT, $filename, O_WRONLY|O_TRUNC)    or die &quot;Can't open $filename for writing: $!\n&quot;;</PRE><PCLASS="para">To get the same effect with <CODECLASS="literal">open</CODE> requires chicanery if the filename has leading or trailing whitespace:</P><PRECLASS="programlisting">$file =~ s#^(\s)#./$1#;open(OUTPUT, &quot;&gt; $file\0&quot;)        or die &quot;Couldn't open $file for OUTPUT : $!\n&quot;;</PRE><PCLASS="para">The substitution protects initial whitespace (this cannot occur in fully specified filenames like <CODECLASS="literal">&quot;/etc/passwd&quot;</CODE>, but only in relative filenames like <CODECLASS="literal">&quot;</CODE> <CODECLASS="literal">passwd&quot;</CODE>). The NULL byte (<CODECLASS="literal">&quot;\0&quot;</CODE>) isn't considered part of the filename by <CODECLASS="literal">open,</CODE> but it does prevent any trailing whitespace from being ignored.</P><PCLASS="para">The magic way <CODECLASS="literal">open</CODE> interprets filenames is nearly always a good thing. You never have to use the special case of <CODECLASS="literal">&quot;-&quot;</CODE> to mean standard input or output. If you write a filter and use a simple <CODECLASS="literal">open</CODE>, users can pass <CODECLASS="literal">&quot;gzip</CODE> <CODECLASS="literal">-dc</CODE> <CODECLASS="literal">bible.gz|&quot;</CODE> as a filename, and your filter will automatically run the decoding program.</P><PCLASS="para">It's only those programs that run under special privilege that should worry about security with <CODECLASS="literal">open</CODE>. When designing programs that will be run on someone else's behalf, like setuid programs or CGI scripts, the prudent programmer always considers whether the user can supply their own filename and thereby cajole what would otherwise appear to be a normal <CODECLASS="literal">open</CODE> used for simple reading into overwriting a file or even running another program. Perl's <BCLASS="emphasis.bold">-T</B> command-line flag to enable taint-checking would take care of this.<ACLASS="indexterm"NAME="ch07-idx-1000009588-0"></A><ACLASS="indexterm"NAME="ch07-idx-1000009588-1"></A><ACLASS="indexterm"NAME="ch07-idx-1000009588-2"></A><ACLASS="indexterm"NAME="ch07-idx-1000009588-3"></A><ACLASS="indexterm"NAME="ch07-idx-1000009588-4"></A><ACLASS="indexterm"NAME="ch07-idx-1000009588-5"></A><ACLASS="indexterm"NAME="ch07-idx-1000009588-6"></A></P></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch07-pgfId-444">See Also</A></H3><PCLASS="para">The <CODECLASS="literal">open</CODE> and <CODECLASS="literal">sysopen</CODE> functions in <ICLASS="filename">perlfunc </I>(1) and <ACLASS="olink"HREF="../prog/ch03_01.htm">Chapter 3</A> of <ACLASS="citetitle"HREF="../prog/index.htm"TITLE="Programming Perl"><CITECLASS="citetitle">Programming Perl</CITE></A>; <ACLASS="xref"HREF="ch07_02.htm"TITLE="Opening a File">Recipe 7.1</A>; <ACLASS="xref"HREF="ch07_08.htm"TITLE="Writing a Filter">Recipe 7.7</A>; <ACLASS="xref"HREF="ch16_03.htm"TITLE="Running Another Program">Recipe 16.2</A>; <ACLASS="xref"HREF="ch19_05.htm"TITLE="Writing a Safe CGI Program">Recipe 19.4</A>; <ACLASS="xref"HREF="ch19_07.htm"TITLE="Executing Commands Without Shell Escapes">Recipe 19.6</A></P></DIV></DIV><DIVCLASS="htmlnav"><P></P><HRALIGN="LEFT"WIDTH="684"TITLE="footer"><TABLEWIDTH="684"BORDER="0"CELLSPACING="0"CELLPADDING="0"><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="228"><ACLASS="sect1"HREF="ch07_02.htm"TITLE="7.1. Opening a File"><IMGSRC="../gifs/txtpreva.gif"ALT="Previous: 7.1. Opening a File"BORDER="0"></A></TD><TDALIGN="CENTER"VALIGN="TOP"WIDTH="228"><ACLASS="book"HREF="index.htm"TITLE="Perl Cookbook"><IMGSRC="../gifs/txthome.gif"ALT="Perl Cookbook"BORDER="0"></A></TD><TDALIGN="RIGHT"VALIGN="TOP"WIDTH="228"><ACLASS="sect1"HREF="ch07_04.htm"TITLE="7.3. Expanding Tildes in Filenames"><IMGSRC="../gifs/txtnexta.gif"ALT="Next: 7.3. Expanding Tildes in Filenames"BORDER="0"></A></TD></TR><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="228">7.1. Opening a File</TD><TDALIGN="CENTER"VALIGN="TOP"WIDTH="228"><ACLASS="index"HREF="index/index.htm"TITLE="Book Index"><IMGSRC="../gifs/index.gif"ALT="Book Index"BORDER="0"></A></TD><TDALIGN="RIGHT"VALIGN="TOP"WIDTH="228">7.3. Expanding Tildes in Filenames</TD></TR></TABLE><HRALIGN="LEFT"WIDTH="684"TITLE="footer"><FONTSIZE="-1"></DIV<!-- LIBRARY NAV BAR --> <img src="../gifs/smnavbar.gif" usemap="#library-map" border="0" alt="Library Navigation Links"><p> <a href="copyrght.htm">Copyright &copy; 2002</a> O'Reilly &amp; Associates. All rights reserved.</font> </p> <map name="library-map"> <area shape="rect" coords="1,0,85,94" href="../index.htm"><area shape="rect" coords="86,1,178,103" href="../lwp/index.htm"><area shape="rect" coords="180,0,265,103" href="../lperl/index.htm"><area shape="rect" coords="267,0,353,105" href="../perlnut/index.htm"><area shape="rect" coords="354,1,446,115" href="../prog/index.htm"><area shape="rect" coords="448,0,526,132" href="../tk/index.htm"><area shape="rect" coords="528,1,615,119" href="../cookbook/index.htm"><area shape="rect" coords="617,0,690,135" href="../pxml/index.htm"></map> </BODY></HTML>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -