<!-- 
RSS generated by JIRA (4.4#649-r158309) at Fri May 24 19:16:44 CDT 2013

It is possible to restrict the fields that are returned in this document by specifying the 'field' parameter in your request.
For example, to request only the issue key and summary add field=key&field=summary to the URL of your request.
For example:
http://dev.clojure.org/jira/si/jira.issueviews:issue-xml/CLJ-870/CLJ-870.xml?field=key&field=summary
-->
<rss version="0.92" >
<channel>
    <title>Clojure JIRA</title>
    <link>http://dev.clojure.org/jira</link>
    <description>This file is an XML representation of an issue</description>
    <language>en-us</language>    <build-info>
        <version>4.4</version>
        <build-number>649</build-number>
        <build-date>25-07-2011</build-date>
    </build-info>

<item>
            <title>[CLJ-870] clojure.string/replace behaves unexpectedly when \ or $ are part of the result string</title>
                <link>http://dev.clojure.org/jira/browse/CLJ-870</link>
                <project id="10010" key="CLJ">Clojure</project>
                        <description>&lt;p&gt;clojure.string/replace uses javas replace function to do it&apos;s work, the replace function has the tricky habit of &apos;double evaluating&apos; the replacement string (third argument). This means that every \ in the string (so i.e. &quot;&lt;br clear=&quot;all&quot; /&gt;&quot;) is evaluated by the java code behind replace.&lt;/p&gt;

&lt;p&gt;Since this behavior isn&apos;t documented it can lead to confusing errors, for example (made up semi real world example to explain the issue):&lt;/p&gt;
&lt;div class=&quot;preformatted panel&quot; style=&quot;border-width: 1px;&quot;&gt;&lt;div class=&quot;preformattedContent panelContent&quot;&gt;
&lt;pre&gt;(clojure.string/replace &quot;c:/windows/&quot; #&quot;/&quot; &quot;\\&quot;)&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This should replace all unix folder separators with windows separators, this crashes with a index out of bound exemption since java tries to evaluate &quot;&lt;br clear=&quot;all&quot; /&gt;&quot; as a semi regexp.&lt;/p&gt;

&lt;p&gt;or&lt;/p&gt;

&lt;div class=&quot;preformatted panel&quot; style=&quot;border-width: 1px;&quot;&gt;&lt;div class=&quot;preformattedContent panelContent&quot;&gt;
&lt;pre&gt;(println (str &quot;\&quot;&quot; (clojure.string/replace &quot;my string with \\ and \&quot; in it&quot; #&quot;[\&quot;\\]&quot; (fn [x] (str &quot;\\&quot; x))) &quot;\&quot;&quot;))&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt; 

&lt;p&gt;The expected result would be:&lt;/p&gt;
&lt;div class=&quot;preformatted panel&quot; style=&quot;border-width: 1px;&quot;&gt;&lt;div class=&quot;preformattedContent panelContent&quot;&gt;
&lt;pre&gt;&quot;my string with \\ and \&quot; in it&quot;&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt; 
&lt;p&gt;the actual result is:&lt;/p&gt;
&lt;div class=&quot;preformatted panel&quot; style=&quot;border-width: 1px;&quot;&gt;&lt;div class=&quot;preformattedContent panelContent&quot;&gt;
&lt;pre&gt;&quot;my string with \ and &quot; in it&quot;&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This should return an &apos;escaped&apos; string, it does not since the &apos;double evaluation&apos; of the return string results in \\\\ being reduced to &lt;br clear=&quot;all&quot; /&gt; again.&lt;/p&gt;

</description>
                <environment>HW/OS/SW indipendant - issue is part of java interface</environment>
            <key id="14913">CLJ-870</key>
            <summary>clojure.string/replace behaves unexpectedly when \ or $ are part of the result string</summary>
                <type id="1" iconUrl="http://dev.clojure.org/jira/images/icons/bug.gif">Defect</type>
                                <priority id="4" iconUrl="http://dev.clojure.org/jira/images/icons/priority_minor.gif">Minor</priority>
                    <status id="6" iconUrl="http://dev.clojure.org/jira/images/icons/status_closed.gif">Closed</status>
                    <resolution id="1">Completed</resolution>
                                <assignee username="stuart.sierra">Stuart Sierra</assignee>
                                <reporter username="licenser">Heinz N. Gies</reporter>
                        <labels>
                    </labels>
                <created>Fri, 4 Nov 2011 05:28:31 -0500</created>
                <updated>Sat, 18 Aug 2012 07:50:41 -0500</updated>
                    <resolved>Sat, 18 Aug 2012 07:50:41 -0500</resolved>
                            <version>Release 1.2</version>
                <version>Release 1.3</version>
                                <fixVersion>Release 1.5</fixVersion>
                                        <due></due>
                    <votes>2</votes>
                        <watches>3</watches>
                        <comments>
                    <comment id="27192" author="licenser" created="Fri, 4 Nov 2011 05:31:57 -0500"  >&lt;p&gt;A working code for the replace example is: &lt;/p&gt;

&lt;div class=&quot;preformatted panel&quot; style=&quot;border-width: 1px;&quot;&gt;&lt;div class=&quot;preformattedContent panelContent&quot;&gt;
&lt;pre&gt;(println (str &quot;\&quot;&quot; (clojure.string/replace &quot;my string with \\ and \&quot; in it&quot; #&quot;[\&quot;\\]&quot; (fn [x] (str  &quot;\\\\&quot;  (if (= x &quot;\\&quot;) &quot;\\&quot;) x))) &quot;\&quot;&quot;))&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;which is horribly ugly since you need to hand escape the backslash or it crashes.&lt;/p&gt;</comment>
                    <comment id="27448" author="stuart.sierra" created="Fri, 9 Dec 2011 15:31:41 -0600"  >&lt;p&gt;Vetted on 1.4.0 master. Needs patch.&lt;/p&gt;</comment>
                    <comment id="27511" author="amalloy" created="Thu, 5 Jan 2012 20:30:04 -0600"  >&lt;p&gt;No hand-escaping is necessary, just use #(java.util.regex.Matcher/quoteReplacement %).&lt;/p&gt;

&lt;p&gt;Edit: I see, we&apos;re talking about when you use a function as a replacement, not a replacement &lt;b&gt;string&lt;/b&gt; like &quot;&lt;br clear=&quot;all&quot; /&gt;x&quot; - the function&apos;s output should not be interpreted as regex replacement, I agree. Looks like it just needs a small patch in clojure.string/replace-by.&lt;/p&gt;</comment>
                    <comment id="27512" author="amalloy" created="Thu, 5 Jan 2012 20:53:14 -0600"  >&lt;p&gt;Patch and test for this issue.&lt;/p&gt;</comment>
                    <comment id="27513" author="jafingerhut" created="Fri, 6 Jan 2012 00:25:52 -0600"  >&lt;p&gt;&lt;a href=&quot;http://dev.clojure.org/jira/browse/CLJ-870&quot; title=&quot;clojure.string/replace behaves unexpectedly when \ or $ are part of the result string&quot;&gt;&lt;del&gt;CLJ-870&lt;/del&gt;&lt;/a&gt;-also-fix-replace-first.patch combines Alan Malloy&apos;s two patches, and adds the same change for replace-first.  I like this change, too, and think replace and replace-first should be consistent with each other in this behavior.&lt;/p&gt;</comment>
                    <comment id="27514" author="jafingerhut" created="Fri, 6 Jan 2012 00:32:50 -0600"  >&lt;p&gt;If there is any interest in a combined patch for this issue, &lt;a href=&quot;http://dev.clojure.org/jira/browse/CLJ-753&quot; title=&quot;clojure.string/replace-first returns nil with replacement fn when regex doesn&amp;#39;t match&quot;&gt;&lt;del&gt;CLJ-753&lt;/del&gt;&lt;/a&gt; and &lt;a href=&quot;http://dev.clojure.org/jira/browse/CLJ-905&quot; title=&quot;clojure.string/replace-first treats \ and $ specially when match is a string, unlike clojure.string/replace&quot;&gt;&lt;del&gt;CLJ-905&lt;/del&gt;&lt;/a&gt; all in one, I&apos;d be happy to merge them.&lt;/p&gt;</comment>
                    <comment id="27543" author="jafingerhut" created="Thu, 12 Jan 2012 00:05:43 -0600"  >&lt;p&gt;Proposed combined patch for &lt;a href=&quot;http://dev.clojure.org/jira/browse/CLJ-753&quot; title=&quot;clojure.string/replace-first returns nil with replacement fn when regex doesn&amp;#39;t match&quot;&gt;&lt;del&gt;CLJ-753&lt;/del&gt;&lt;/a&gt;, &lt;a href=&quot;http://dev.clojure.org/jira/browse/CLJ-870&quot; title=&quot;clojure.string/replace behaves unexpectedly when \ or $ are part of the result string&quot;&gt;&lt;del&gt;CLJ-870&lt;/del&gt;&lt;/a&gt;, and &lt;a href=&quot;http://dev.clojure.org/jira/browse/CLJ-905&quot; title=&quot;clojure.string/replace-first treats \ and $ specially when match is a string, unlike clojure.string/replace&quot;&gt;&lt;del&gt;CLJ-905&lt;/del&gt;&lt;/a&gt;, since they all affect the behavior of clojure.string/replace and replace-first.&lt;/p&gt;</comment>
                    <comment id="27643" author="stuart.sierra" created="Fri, 3 Feb 2012 09:15:43 -0600"  >&lt;p&gt;The 1/12/2012 combined patch is not in correct format. Please recreate, see &lt;a href=&quot;http://clojure.org/patches&quot;&gt;http://clojure.org/patches&lt;/a&gt; for correct format.&lt;/p&gt;</comment>
                    <comment id="27652" author="jafingerhut" created="Sat, 4 Feb 2012 10:51:50 -0600"  >&lt;p&gt;&lt;a href=&quot;http://dev.clojure.org/jira/browse/CLJ-753&quot; title=&quot;clojure.string/replace-first returns nil with replacement fn when regex doesn&amp;#39;t match&quot;&gt;&lt;del&gt;CLJ-753&lt;/del&gt;&lt;/a&gt;-870-905-combined-fix2.patch should have proper patch format.&lt;/p&gt;</comment>
                    <comment id="27884" author="jafingerhut" created="Tue, 28 Feb 2012 12:38:29 -0600"  >&lt;p&gt;Attaching slightly improved patch &lt;a href=&quot;http://dev.clojure.org/jira/browse/CLJ-753&quot; title=&quot;clojure.string/replace-first returns nil with replacement fn when regex doesn&amp;#39;t match&quot;&gt;&lt;del&gt;CLJ-753&lt;/del&gt;&lt;/a&gt;-870-905-combined-fix3.patch, along with a README to explain in gory detail the behavior and performance changes to clojure.string/replace and clojure.string/replace-first, in case it would help anyone review the changes.  Deleting my older patches.&lt;/p&gt;</comment>
                    <comment id="29153" author="aaron" created="Tue, 14 Aug 2012 20:44:20 -0500"  >&lt;p&gt;This is a small nit pick, but re-qr is a pretty non-descriptive name. Perhaps we could change it to re-quote-replacement?&lt;/p&gt;</comment>
                    <comment id="29175" author="jafingerhut" created="Wed, 15 Aug 2012 11:19:59 -0500"  >&lt;p&gt;Patches clj-753-870-905-combined-fix4.patch dated Aug 15 2012 and the patch that Aaron reviewed, &lt;a href=&quot;http://dev.clojure.org/jira/browse/CLJ-753&quot; title=&quot;clojure.string/replace-first returns nil with replacement fn when regex doesn&amp;#39;t match&quot;&gt;&lt;del&gt;CLJ-753&lt;/del&gt;&lt;/a&gt;-870-905-combined-fix3.patch dated Feb 28 2012, are almost identical.&lt;/p&gt;

&lt;p&gt;fix3 uses the name re-qr for a function, where fix4 uses the name re-quote-replacement.  I have no strong preference for either of them.&lt;/p&gt;</comment>
                    <comment id="29177" author="jafingerhut" created="Wed, 15 Aug 2012 11:23:30 -0500"  >&lt;p&gt;Added patch addressing what I think is Aaron&apos;s reason for changing state to Incomplete, so as a result I am changing state back to its former Vetted state.  If there is something else a non-screener should be doing to bring Incomplete tickets to the attention of screeners, please let me know, and I will document it here: &lt;a href=&quot;http://dev.clojure.org/display/design/JIRA+workflow&quot;&gt;http://dev.clojure.org/display/design/JIRA+workflow&lt;/a&gt;&lt;/p&gt;</comment>
                    <comment id="29188" author="stuart.sierra" created="Wed, 15 Aug 2012 14:42:33 -0500"  >&lt;p&gt;I will be looking at this.&lt;/p&gt;</comment>
                    <comment id="29209" author="stuart.sierra" created="Fri, 17 Aug 2012 07:55:59 -0500"  >&lt;p&gt;Screened. This is an adequate fix for this particular problem, given the current API.&lt;/p&gt;

&lt;p&gt;However, the long and complicated docstring proves that &lt;tt&gt;replace&lt;/tt&gt; and &lt;tt&gt;replace-first&lt;/tt&gt; should each be four separate functions:&lt;/p&gt;

&lt;p&gt;&lt;tt&gt;code&lt;/tt&gt;&lt;br/&gt;
replace-char   &lt;span class=&quot;error&quot;&gt;&amp;#91;input char char&amp;#93;&lt;/span&gt;&lt;br/&gt;
replace-string &lt;span class=&quot;error&quot;&gt;&amp;#91;input string string&amp;#93;&lt;/span&gt;&lt;br/&gt;
replace-re     &lt;span class=&quot;error&quot;&gt;&amp;#91;input pattern string&amp;#93;&lt;/span&gt;&lt;br/&gt;
replace-re-by  &lt;span class=&quot;error&quot;&gt;&amp;#91;input pattern fn&amp;#93;&lt;/span&gt;&lt;br/&gt;
&lt;tt&gt;code&lt;/tt&gt;&lt;/p&gt;

&lt;p&gt;This is how these functions were originally written back in the days of clojure.contrib.str-utils. This would be a minor breaking change.&lt;/p&gt;</comment>
                </comments>
                    <attachments>
                    <attachment id="10760" name="0001-Add-tests-for-870.patch" size="964" author="amalloy" created="Thu, 5 Jan 2012 20:53:14 -0600" />
                    <attachment id="10761" name="0002-Fix-870-by-using-quoteReplacement.patch" size="1205" author="amalloy" created="Thu, 5 Jan 2012 20:53:14 -0600" />
                    <attachment id="10971" name="CLJ-753-870-905-combined-fix3.patch" size="8936" author="jafingerhut" created="Tue, 28 Feb 2012 12:38:29 -0600" />
                    <attachment id="10972" name="CLJ-753-870-905-combined-fix3.readme.txt" size="3571" author="jafingerhut" created="Tue, 28 Feb 2012 12:38:29 -0600" />
                    <attachment id="11434" name="clj-753-870-905-combined-fix4.patch" size="9071" author="jafingerhut" created="Wed, 15 Aug 2012 11:19:59 -0500" />
                </attachments>
            <subtasks>
        </subtasks>
                <customfields>
                                <customfield id="customfield_10002" key="com.atlassian.jira.plugin.system.customfieldtypes:select">
                <customfieldname>Approval</customfieldname>
                <customfieldvalues>
                        <customfieldvalue key="10007">Ok</customfieldvalue>

                </customfieldvalues>
            </customfield>
                                                                                    <customfield id="customfield_10010" key="com.pyxis.greenhopper.jira:gh-global-rank">
                <customfieldname>Global Rank</customfieldname>
                <customfieldvalues>
                    
                </customfieldvalues>
            </customfield>
                                            <customfield id="customfield_10000" key="com.atlassian.jira.plugin.system.customfieldtypes:select">
                <customfieldname>Patch</customfieldname>
                <customfieldvalues>
                        <customfieldvalue key="10002">Code and Test</customfieldvalue>

                </customfieldvalues>
            </customfield>
                                                                                    <customfield id="customfield_10003" key="com.atlassian.jira.plugin.system.customfieldtypes:userpicker">
                <customfieldname>Waiting On</customfieldname>
                <customfieldvalues>
                    <customfieldvalue>richhickey</customfieldvalue>
                </customfieldvalues>
            </customfield>
                            </customfields>
    </item>
</channel>
</rss>