<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0"><channel><title>mikeash.com pyblog/dont-use-strnstr.html comments</title><link>http://www.mikeash.com/?page=pyblog/dont-use-strnstr.html#comments</link><description>mikeash.com Recent Comments</description><lastBuildDate>Mon, 11 May 2026 23:51:47 GMT</lastBuildDate><generator>PyRSS2Gen-1.0.0</generator><docs>http://blogs.law.harvard.edu/tech/rss</docs><item><title>H W - 2008-04-01 14:59:50</title><link>http://www.mikeash.com/?page=pyblog/dont-use-strnstr.html#comments</link><description>This was just fixed in Apple's latest security update. It only took half a year...! </description><guid isPermaLink="true">3e898f6c46a0eb29ff66ecf8d8fc8b63</guid><pubDate>Tue, 01 Apr 2008 14:59:50 GMT</pubDate></item><item><title>mikeash - 2007-10-21 19:27:00</title><link>http://www.mikeash.com/?page=pyblog/dont-use-strnstr.html#comments</link><description>As I stated in my response to Andrew, the man page &lt;i&gt;clearly states&lt;/i&gt; that it does not expect a null-terminated string. Perhaps this is not the intention, but if so then the man page is defective.
&lt;br /&gt;</description><guid isPermaLink="true">40aedaf11504ab79baf8e249ed0b7734</guid><pubDate>Sun, 21 Oct 2007 19:27:00 GMT</pubDate></item><item><title>Jean-Daniel Dupas - 2007-10-19 17:59:00</title><link>http://www.mikeash.com/?page=pyblog/dont-use-strnstr.html#comments</link><description>According to the man page, no more than len characters are &amp;amp;#8220;searched&amp;amp;#8221;. It does not say that no more than len characters are readed.&amp;lt;br /&amp;gt;
&lt;br /&gt;Else this function would be called strlstr().&amp;lt;br /&amp;gt;
&lt;br /&gt;The strn&amp;amp;#8230;() functions was not created to avoid buffer overflow, but to works on substring.&amp;lt;br /&amp;gt;
&lt;br /&gt;They all expects to have a valid C string as argument.
&lt;br /&gt;</description><guid isPermaLink="true">ae63f84820791091e6c5bf1986221399</guid><pubDate>Fri, 19 Oct 2007 17:59:00 GMT</pubDate></item><item><title>Steven Fisher - 2007-10-04 17:37:00</title><link>http://www.mikeash.com/?page=pyblog/dont-use-strnstr.html#comments</link><description>That&amp;amp;#8217;s pretty much what I was thinking. Since it&amp;amp;#8217;s not a write or an execution. there shouldn&amp;amp;#8217;t be any security implications. (Which in a way is too bad; it would probably be fixed faster if there was that potential.)
&lt;br /&gt;</description><guid isPermaLink="true">06033c195b96cade8d06f14050684dc0</guid><pubDate>Thu, 04 Oct 2007 17:37:00 GMT</pubDate></item><item><title>mikeash - 2007-10-04 01:43:00</title><link>http://www.mikeash.com/?page=pyblog/dont-use-strnstr.html#comments</link><description>It could potentially result in a denial of service, if a malicious person were able to transmit data which would trigger the segfault in a remote process. It &lt;i&gt;might&lt;/i&gt; lead to a bit of data leakage by crafting malicious data and then seeing whether the remote process dies or not, but even this is pretty farfetched. I don&amp;amp;#8217;t see any way for it to remote code execution by itself.
&lt;br /&gt;</description><guid isPermaLink="true">1e93b41f0ab7ba7d2db4a89aeb74bd2e</guid><pubDate>Thu, 04 Oct 2007 01:43:00 GMT</pubDate></item><item><title>Steven Fisher - 2007-10-03 23:47:00</title><link>http://www.mikeash.com/?page=pyblog/dont-use-strnstr.html#comments</link><description>Definitely looks like a simple bug to me. It looks like it isn&amp;amp;#8217;t a security problem, but I&amp;amp;#8217;m not sure about that. :)
&lt;br /&gt;</description><guid isPermaLink="true">8859b347333f7664adbe339c46a7ed91</guid><pubDate>Wed, 03 Oct 2007 23:47:00 GMT</pubDate></item><item><title>mikeash - 2007-10-03 22:33:00</title><link>http://www.mikeash.com/?page=pyblog/dont-use-strnstr.html#comments</link><description>Wow, lots of feedback all of a sudden. Let&amp;amp;#8217;s take it individually.&amp;lt;br /&amp;gt;
&lt;br /&gt;&amp;lt;br /&amp;gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Wormwood, it is not more correct. It does avoid this bug but it causes a new one. Subtracting the length of the string to be searched will cause it to miss matches at the very end of the string.&amp;lt;br /&amp;gt;
&lt;br /&gt;&amp;lt;br /&amp;gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;alastair, I don&amp;amp;#8217;t care about portability to other OSes but I absolutely need my code to work on Tiger, so features in Leopard are useless to me. What&amp;amp;#8217;s more, I was not able to find any POSIX/SUSv3 equivalent to strnstr. If you know of one, I&amp;amp;#8217;d appreciate hearing about it. And of course reading off the end of the string is legal as long as you don&amp;amp;#8217;t cross page boundaries, but the whole problem is that it does read past page boundaries, causing a segfault.&amp;lt;br /&amp;gt;
&lt;br /&gt;&amp;lt;br /&amp;gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Andrew, I dispute your dispute! The function is quite clear that it will not read beyond the length you give it. That is really the entire reason it exists. Whether or not the string is terminated after the length you give it is irrelevant, because it has no way of legally finding out whether there&amp;amp;#8217;s a terminator or not. You will also notice that the man page goes out of its way to &lt;i&gt;explicitly&lt;/i&gt; state when strings are terminated. The description of strstr says that it, &amp;amp;#8220;locates the first occurrence of the &lt;i&gt;null-terminated&lt;/i&gt; string s2 in the &lt;i&gt;null-terminated&lt;/i&gt; string s1.&amp;amp;#8221; (Emphasis mine.) The description of strnstr states, &amp;amp;#8220;locates the first occurrence of the &lt;i&gt;null-terminated&lt;/i&gt; string s2 in the string s1&amp;amp;#8230;.&amp;amp;#8221; (Emphasis mine, again.) Note how it neglects to say that s1 is null-terminated. I cannot imagine that this is anything other than intentional.
&lt;br /&gt;</description><guid isPermaLink="true">18a3f70028a994b6a1ba50c9daf35c8d</guid><pubDate>Wed, 03 Oct 2007 22:33:00 GMT</pubDate></item><item><title>Chris K - 2007-10-02 21:31:00</title><link>http://www.mikeash.com/?page=pyblog/dont-use-strnstr.html#comments</link><description>Well, at least you motivated me to report another apple bug, this one in the regex library. Try these two:&amp;lt;br /&amp;gt;
&lt;br /&gt;echo ab | sed -nE s/((a)|(b)){0,}//p&amp;lt;br /&amp;gt;
&lt;br /&gt;echo ab | sed -nE s/((a)|(b)){0,2}//p&amp;lt;br /&amp;gt;
&lt;br /&gt;Hint: They should both have returned [b::b]
&lt;br /&gt;</description><guid isPermaLink="true">db6d73d2c6d854a0c83b8932fc6e9399</guid><pubDate>Tue, 02 Oct 2007 21:31:00 GMT</pubDate></item><item><title>Andrew - 2007-10-02 21:20:00</title><link>http://www.mikeash.com/?page=pyblog/dont-use-strnstr.html#comments</link><description>I dispute that the man page allows for the buffer (&amp;amp;#8220;str&amp;amp;#8221; in your example, &amp;amp;#8220;big&amp;amp;#8221; in the man page) to lack a null byte (man pages are terse because they depend on context: see the def&amp;amp;#8217;n of &amp;amp;#8220;big&amp;amp;#8221; under the description for strstr [no &amp;amp;#8220;n&amp;amp;#8221;] and note the fn is not called memnstr).  Because it lacks a null byte the first argument you&amp;amp;#8217;re passing to strnstr isn&amp;amp;#8217;t a string so the behavior is not disallowed.  Before you claim that searching no more than size/len bytes guarantees it won&amp;amp;#8217;t read past the end of your buffer, I would suggest that you don&amp;amp;#8217;t know why it is reading the character one past the end of your buffer.  It could just be that it does the end of string test before the &amp;amp;#8220;search exceeds size/len&amp;amp;#8221; test.  I agree the behavior in this case could be more friendly but it certainly cannot be considered a bug, merely unspecified.
&lt;br /&gt;</description><guid isPermaLink="true">9f52f23804ff6a2a04dd76397120bd6c</guid><pubDate>Tue, 02 Oct 2007 21:20:00 GMT</pubDate></item><item><title>Colin Percival - 2007-10-02 19:34:00</title><link>http://www.mikeash.com/?page=pyblog/dont-use-strnstr.html#comments</link><description>FreeBSD fixed this in February 2005: &amp;lt;a href="&lt;a href="http://www.freebsd.org/cgi/query-pr.cgi?pr=77369"&gt;http://www.freebsd.org/cgi/query-pr.cgi?pr=77369&lt;/a&gt;" rel="nofollow"&amp;gt;&lt;a href="http://www.freebsd.org/cgi/query-pr.cgi?..&amp;amp;lt"&gt;http://www.freebsd.org/cgi/query-pr.cgi?..&amp;lt;&lt;/a&gt;;/a&amp;gt;
&lt;br /&gt;</description><guid isPermaLink="true">70cb35bb63b6d45a43d9ad398a5d6366</guid><pubDate>Tue, 02 Oct 2007 19:34:00 GMT</pubDate></item><item><title>alastair - 2007-10-02 18:52:00</title><link>http://www.mikeash.com/?page=pyblog/dont-use-strnstr.html#comments</link><description>strnstr() isn&amp;amp;#8217;t a standard function anyway; it&amp;amp;#8217;s a FreeBSD extension. I&amp;amp;#8217;d be inclined to stick either to ISO C functions (if you need Windows portability) or to POSIX/SUSv3 functions (which, in Leopard, have been independently validated against the specification, so you know they behave the same way on other certified UNIX platforms).&amp;lt;br /&amp;gt;
&lt;br /&gt;&amp;lt;br /&amp;gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;I should add, by the way, that it&amp;amp;#8217;s quite common for implementations of the string functions to read over the &amp;amp;#8220;end&amp;amp;#8221; of the string by a small amount. Usually they do this so that they can read words (or even larger elements with SSE/Altivec), and normally this won&amp;amp;#8217;t cause a problem because they won&amp;amp;#8217;t issue a read that straddles a page boundary (i.e. they&amp;amp;#8217;ll read, at most, up to the end of the page where your NUL terminator is).
&lt;br /&gt;</description><guid isPermaLink="true">437d942c3b1975594f20f689aabd14a2</guid><pubDate>Tue, 02 Oct 2007 18:52:00 GMT</pubDate></item><item><title>Wormwood - 2007-10-02 18:20:00</title><link>http://www.mikeash.com/?page=pyblog/dont-use-strnstr.html#comments</link><description>Forgive my naiveté... but wouldn&amp;amp;#8217;t the following line of code be more correct (or otherwise avoid a bug)?&amp;lt;br /&amp;gt;
&lt;br /&gt;&amp;lt;br /&amp;gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;strnstr( str, &amp;amp;#8220;aa&amp;amp;#8221;, size &amp;amp;#8211; strlen(&amp;amp;#8220;aa&amp;amp;#8221&amp;lt;img src="/blog/pivot/includes/emot/e_121.gif" alt=";)" align="middle" /&amp;gt; );&amp;lt;br /&amp;gt;
&lt;br /&gt;&amp;lt;br /&amp;gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;The man page is a little ambiguous with how &amp;amp;#8220;not more than len characters are searched&amp;amp;#8221; is phrased or intended.  The implementation may vary well define &amp;amp;#8220;search&amp;amp;#8221; as matching the first character and overlook the length of the search string when determining when the internal loop stops.  (strnstr is from BSD, so I wouldn&amp;amp;#8217;t be surprised if the bug is present or independently fixed there.)
&lt;br /&gt;</description><guid isPermaLink="true">5b6fdaba245ecde30cbe45f1c9688957</guid><pubDate>Tue, 02 Oct 2007 18:20:00 GMT</pubDate></item><item><title>mikeash - 2007-09-27 04:59:00</title><link>http://www.mikeash.com/?page=pyblog/dont-use-strnstr.html#comments</link><description>I agree that C strings are unpleasant, but for doing some initial parsing of data whose encoding is not yet known, I haven&amp;amp;#8217;t found a better way. In this case, I&amp;amp;#8217;m parsing an HTTP request which is assumed to be UTF-8 but, for paranoia&amp;amp;#8217;s sake, I want to be able to fall back to Latin-1. To this end I need to find the end of the request in the incoming data but all of the higher-level string APIs require you to give them an encoding, and Cocoa&amp;amp;#8217;s higher-level data APIs don&amp;amp;#8217;t have this kind of search functionality.
&lt;br /&gt;</description><guid isPermaLink="true">75e54226a3c156b9e0c53d0fa29b6bb1</guid><pubDate>Thu, 27 Sep 2007 04:59:00 GMT</pubDate></item><item><title>Ahruman - 2007-09-26 23:35:00</title><link>http://www.mikeash.com/?page=pyblog/dont-use-strnstr.html#comments</link><description>C strings: jus say AarrghaarrghpleeassennononoUGH.
&lt;br /&gt;</description><guid isPermaLink="true">33a224aae9be127c1dbdcbb870fd789d</guid><pubDate>Wed, 26 Sep 2007 23:35:00 GMT</pubDate></item></channel></rss>
