Boost C++ Libraries: Ticket #9518: string_ref::rfind return value offset https://svn.boost.org/trac10/ticket/9518 <p> The value returned from basic_string_ref::rfind() is calculated based on the where the end of the target string was found, but is not adjusted for the length of that string. </p> <p> E.g, given </p> <pre class="wiki"> const char pstr[] = "abcdabc\0abcd"; string_view sv(pstr, sizeof(pstr)-1); const char * pabc = "abc"; string_view svabc(pabc); string_ref::size_type rv = sv.rfind(svabc); </pre><p> <code></code>rv<code></code> will have the value 10 (referencing the last 'c') instead of 8 (referencing the 'a' that starts the match). </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/9518 Trac 1.4.3 bimaster@… Thu, 13 Aug 2015 08:37:07 GMT <link>https://svn.boost.org/trac10/ticket/9518#comment:1 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/9518#comment:1</guid> <description> <p> proposed fix (not fixed yet in 1.59.beta): </p> <div class="wiki-code"><div class="code"><pre><span class="n">size_type</span> <span class="nf">rfind</span><span class="p">(</span><span class="n">basic_string_ref</span> <span class="n">x</span><span class="p">,</span> <span class="kt">size_t</span> <span class="n">pos</span> <span class="o">=</span> <span class="n">npos</span><span class="p">)</span> <span class="k">const</span> <span class="p">{</span> <span class="n">const_reverse_iterator</span> <span class="n">s</span> <span class="o">=</span> <span class="k">this</span><span class="o">-&gt;</span><span class="n">crbegin</span><span class="p">();</span> <span class="n">const_reverse_iterator</span> <span class="n">e</span> <span class="o">=</span> <span class="k">this</span><span class="o">-&gt;</span><span class="n">crend</span><span class="p">();</span> <span class="k">if</span><span class="p">(</span><span class="n">pos</span> <span class="o">&lt;</span> <span class="n">size</span><span class="p">())</span> <span class="n">s</span> <span class="o">+=</span> <span class="n">pos</span><span class="p">;</span> <span class="n">const_reverse_iterator</span> <span class="n">iter</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">search</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">e</span><span class="p">,</span> <span class="n">x</span><span class="p">.</span><span class="n">crbegin</span><span class="p">(),</span> <span class="n">x</span><span class="p">.</span><span class="n">crend</span><span class="p">(),</span> <span class="n">traits</span><span class="o">::</span><span class="n">eq</span><span class="p">);</span> <span class="c1">// the only case where substring is searched, reverse_distance not applicable</span> <span class="k">return</span> <span class="n">iter</span> <span class="o">==</span> <span class="n">e</span> <span class="o">?</span> <span class="nl">npos</span> <span class="p">:</span> <span class="n">len_</span> <span class="o">-</span> <span class="n">std</span><span class="o">::</span><span class="n">distance</span><span class="p">(</span><span class="k">this</span><span class="o">-&gt;</span><span class="n">crbegin</span><span class="p">(),</span> <span class="n">iter</span><span class="p">)</span> <span class="o">-</span> <span class="n">x</span><span class="p">.</span><span class="n">size</span><span class="p">();</span> <span class="p">}</span> </pre></div></div> </description> <category>Ticket</category> </item> <item> <author>bibmaster@…</author> <pubDate>Thu, 13 Aug 2015 09:26:15 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/9518#comment:2 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/9518#comment:2</guid> <description> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/9518#comment:1" title="Comment 1">bimaster@…</a>: </p> <blockquote class="citation"> <p> proposed fix (not fixed yet in 1.59.beta): </p> <div class="wiki-code"><div class="code"><pre><span class="n">size_type</span> <span class="nf">rfind</span><span class="p">(</span><span class="n">basic_string_ref</span> <span class="n">x</span><span class="p">,</span> <span class="kt">size_t</span> <span class="n">pos</span> <span class="o">=</span> <span class="n">npos</span><span class="p">)</span> <span class="k">const</span> <span class="p">{</span> <span class="n">const_reverse_iterator</span> <span class="n">s</span> <span class="o">=</span> <span class="k">this</span><span class="o">-&gt;</span><span class="n">crbegin</span><span class="p">();</span> <span class="n">const_reverse_iterator</span> <span class="n">e</span> <span class="o">=</span> <span class="k">this</span><span class="o">-&gt;</span><span class="n">crend</span><span class="p">();</span> <span class="k">if</span><span class="p">(</span><span class="n">pos</span> <span class="o">&lt;</span> <span class="n">size</span><span class="p">())</span> <span class="n">s</span> <span class="o">+=</span> <span class="n">pos</span><span class="p">;</span> <span class="n">const_reverse_iterator</span> <span class="n">iter</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">search</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">e</span><span class="p">,</span> <span class="n">x</span><span class="p">.</span><span class="n">crbegin</span><span class="p">(),</span> <span class="n">x</span><span class="p">.</span><span class="n">crend</span><span class="p">(),</span> <span class="n">traits</span><span class="o">::</span><span class="n">eq</span><span class="p">);</span> <span class="c1">// the only case where substring is searched, reverse_distance not applicable</span> <span class="k">return</span> <span class="n">iter</span> <span class="o">==</span> <span class="n">e</span> <span class="o">?</span> <span class="nl">npos</span> <span class="p">:</span> <span class="n">len_</span> <span class="o">-</span> <span class="n">std</span><span class="o">::</span><span class="n">distance</span><span class="p">(</span><span class="k">this</span><span class="o">-&gt;</span><span class="n">crbegin</span><span class="p">(),</span> <span class="n">iter</span><span class="p">)</span> <span class="o">-</span> <span class="n">x</span><span class="p">.</span><span class="n">size</span><span class="p">();</span> <span class="p">}</span> </pre></div></div></blockquote> <p> ooops, pos in std::string denotes offset from start, so </p> <div class="wiki-code"><div class="code"><pre><span class="k">if</span><span class="p">(</span><span class="n">pos</span> <span class="o">&lt;</span> <span class="n">size</span><span class="p">())</span> <span class="n">s</span> <span class="o">+=</span> <span class="p">(</span><span class="n">size</span><span class="p">()</span> <span class="o">-</span> <span class="n">pos</span><span class="p">);</span> </pre></div></div> </description> <category>Ticket</category> </item> <item> <author>bibmaster@…</author> <pubDate>Thu, 13 Aug 2015 10:24:05 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/9518#comment:3 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/9518#comment:3</guid> <description> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/9518#comment:2" title="Comment 2">bibmaster@…</a>: </p> <blockquote class="citation"> <p> ooops, pos in std::string denotes offset from start, so </p> <div class="wiki-code"><div class="code"><pre><span class="k">if</span><span class="p">(</span><span class="n">pos</span> <span class="o">&lt;</span> <span class="n">size</span><span class="p">())</span> <span class="n">s</span> <span class="o">+=</span> <span class="p">(</span><span class="n">size</span><span class="p">()</span> <span class="o">-</span> <span class="n">pos</span><span class="p">);</span> </pre></div></div></blockquote> <p> hmmm, but pos shall be included in search range: </p> <div class="wiki-code"><div class="code"><pre><span class="k">if</span><span class="p">(</span><span class="n">pos</span> <span class="o">&lt;</span> <span class="n">size</span><span class="p">())</span> <span class="n">s</span> <span class="o">+=</span> <span class="p">(</span><span class="n">size</span><span class="p">()</span> <span class="o">-</span> <span class="n">pos</span> <span class="o">+</span> <span class="mi">1</span><span class="p">);</span> </pre></div></div> </description> <category>Ticket</category> </item> <item> <author>bibmaster@…</author> <pubDate>Thu, 13 Aug 2015 10:25:39 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/9518#comment:4 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/9518#comment:4</guid> <description> <blockquote class="citation"> <div class="wiki-code"><div class="code"><pre><span class="k">if</span><span class="p">(</span><span class="n">pos</span> <span class="o">&lt;</span> <span class="n">size</span><span class="p">())</span> <span class="n">s</span> <span class="o">+=</span> <span class="p">(</span><span class="n">size</span><span class="p">()</span> <span class="o">-</span> <span class="n">pos</span> <span class="o">+</span> <span class="mi">1</span><span class="p">);</span> </pre></div></div></blockquote> <p> error in sign: </p> <div class="wiki-code"><div class="code"><pre><span class="k">if</span><span class="p">(</span><span class="n">pos</span> <span class="o">&lt;</span> <span class="n">size</span><span class="p">())</span> <span class="n">s</span> <span class="o">+=</span> <span class="p">(</span><span class="n">size</span><span class="p">()</span> <span class="o">-</span> <span class="n">pos</span> <span class="o">-</span> <span class="mi">1</span><span class="p">);</span> </pre></div></div> </description> <category>Ticket</category> </item> <item> <author>bibmaster@…</author> <pubDate>Thu, 13 Aug 2015 10:45:37 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/9518#comment:5 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/9518#comment:5</guid> <description> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/9518#comment:4" title="Comment 4">bibmaster@…</a>: well, error again: pos is the maximum position where found substring may start: </p> <div class="wiki-code"><div class="code"><pre><span class="k">if</span><span class="p">(</span><span class="n">pos</span> <span class="o">&lt;</span> <span class="n">size</span><span class="p">()</span> <span class="o">&amp;&amp;</span> <span class="n">pos</span> <span class="o">+</span> <span class="n">x</span><span class="p">.</span><span class="n">size</span><span class="p">()</span> <span class="o">&lt;</span> <span class="n">size</span><span class="p">())</span> <span class="n">s</span> <span class="o">+=</span> <span class="p">(</span><span class="n">size</span><span class="p">()</span> <span class="o">-</span> <span class="n">pos</span> <span class="o">-</span> <span class="n">x</span><span class="p">.</span><span class="n">size</span><span class="p">()</span> <span class="o">-</span> <span class="mi">1</span><span class="p">);</span> </pre></div></div> </description> <category>Ticket</category> </item> <item> <author>bibmaster@…</author> <pubDate>Thu, 13 Aug 2015 12:08:23 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/9518#comment:6 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/9518#comment:6</guid> <description> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/9518#comment:5" title="Comment 5">bibmaster@…</a>: </p> <blockquote class="citation"> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/9518#comment:4" title="Comment 4">bibmaster@…</a>: well, error again: </p> </blockquote> <p> and again... </p> <div class="wiki-code"><div class="code"><pre><span class="k">if</span><span class="p">(</span><span class="n">pos</span> <span class="o">&lt;</span> <span class="n">size</span><span class="p">()</span> <span class="o">&amp;&amp;</span> <span class="p">(</span><span class="n">pos</span> <span class="o">+</span> <span class="n">x</span><span class="p">.</span><span class="n">size</span><span class="p">())</span> <span class="o">&lt;</span> <span class="n">size</span><span class="p">())</span> <span class="n">s</span> <span class="o">+=</span> <span class="p">(</span><span class="n">size</span><span class="p">()</span> <span class="o">-</span> <span class="p">(</span><span class="n">pos</span> <span class="o">+</span> <span class="n">x</span><span class="p">.</span><span class="n">size</span><span class="p">()));</span> </pre></div></div> </description> <category>Ticket</category> </item> <item> <author>Peter A. Bigot <pab@…></author> <pubDate>Thu, 13 Aug 2015 13:07:46 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/9518#comment:7 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/9518#comment:7</guid> <description> <p> Would you please wait until you have a solution that you're absolutely sure works before posting candidate fixes? Though I'm sure the Boost folks would appreciate a patch (which probably should be submittted through the mailing list or a pull request), I'm getting email on each one of these and it's a bit annoying. Thanks. </p> </description> <category>Ticket</category> </item> <item> <author>Alex L. <alxlaus@…></author> <pubDate>Sun, 18 Oct 2015 17:09:06 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/9518#comment:8 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/9518#comment:8</guid> <description> <p> In my opinion the proposed fix goes in the wrong direction. The core of the problem lies in the reverse_distance helper, which ought to incorporate a more general length of the string as an offset (currently it is hard-coded to "1", which nicely fits the other usages, but not that in rfind). </p> <p> I created a PR along with a test case here: <a class="ext-link" href="https://github.com/boostorg/utility/pull/21"><span class="icon">​</span>https://github.com/boostorg/utility/pull/21</a> </p> </description> <category>Ticket</category> </item> <item> <author>denis.martinez@…</author> <pubDate>Fri, 05 Aug 2016 14:14:04 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/9518#comment:9 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/9518#comment:9</guid> <description> <p> My dev team has hit this bug a few times. It would be really great to have the proposed fix applied, sadly there doesn't seem to be any activity for a bit of time. </p> <p> This bug remains present in the 1.61.0 release of Boost. </p> <pre class="wiki">boost::string_ref("abcdefg").rfind("cde") -&gt; 4 std::string("abcdefg").rfind("cde") -&gt; 2 </pre> </description> <category>Ticket</category> </item> <item> <dc:creator>Marshall Clow</dc:creator> <pubDate>Sun, 14 Aug 2016 18:23:08 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/9518#comment:10 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/9518#comment:10</guid> <description> <p> Commit 39577f86d1b3a260afc1e7f7caec1ee8f12594bb should fix this. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Marshall Clow</dc:creator> <pubDate>Wed, 17 Aug 2016 20:01:03 GMT</pubDate> <title>status changed; resolution set https://svn.boost.org/trac10/ticket/9518#comment:11 https://svn.boost.org/trac10/ticket/9518#comment:11 <ul> <li><strong>status</strong> <span class="trac-field-old">new</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> → <span class="trac-field-new">fixed</span> </li> </ul> <p> Merged to master. </p> Ticket