Fixed encoding of '+' character on search pages links

As revealed by issue #216
This commit is contained in:
luccioman 2018-08-20 17:01:08 +02:00
parent b726b2b532
commit 5b60b4225f
6 changed files with 59 additions and 17 deletions

View File

@ -37,7 +37,7 @@
<span class="visible-sm glyphicon glyphicon-search"><b class="caret"></b></span>
</a>
<ul class="dropdown-menu" role="menu">
<li id="header_websearch"><a href="index.html#(authSearch)#::?auth#(/authSearch)#" onclick="this.href='index.html?#(authSearch)#::auth&#(/authSearch)#former='+document.searchform.search.value">Web Search</a></li>
<li id="header_websearch"><a href="index.html#(authSearch)#::?auth#(/authSearch)#" onclick="this.href='index.html?#(authSearch)#::auth&#(/authSearch)#former='+encodeURIComponent(document.searchform.search.value)">Web Search</a></li>
<li id="header_filesearch"><a href="yacyinteractive.html" onclick="this.href='yacyinteractive.html?handover='+document.searchform.search.value">File Search</a></li>
<li id="header_comparesearch"><a href="compare_yacy.html?display=0">Compare Search</a></li>
<li id="header_hostbrowser"><a href="HostBrowser.html?hosts=">Index Browser</a></li>

View File

@ -17,7 +17,7 @@
<li id="header_search" class="dropdown">
<a href="#" data-toggle="dropdown" class="dropdown-toggle" role="button" aria-haspopup="true" aria-expanded="false">Search Interfaces<b class="caret"></b></a>
<ul class="dropdown-menu" role="menu">
<li id="header_websearch"><a href="index.html#(authorized)#::?auth#(/authorized)#" onclick="this.href='index.html?#(authorized)#::auth&#(/authorized)#former='+document.searchform.search.value">Web Search</a></li>
<li id="header_websearch"><a href="index.html#(authorized)#::?auth#(/authorized)#" onclick="this.href='index.html?#(authorized)#::auth&#(/authorized)#former='+encodeURIComponent(document.searchform.search.value)">Web Search</a></li>
<li id="header_filesearch"><a href="yacyinteractive.html" onclick="this.href='yacyinteractive.html?handover='+document.searchform.search.value">File Search</a></li>
<li id="header_comparesearch"><a href="compare_yacy.html?display=0">Compare Search</a></li>
<li id="header_hostbrowser"><a href="HostBrowser.html?hosts=">Index Browser</a></li>

View File

@ -79,7 +79,7 @@
#(searchaudio)#::<label><input type="radio" id="audio" name="contentdom" value="audio" #(check)#::checked="checked"#(/check)# />&nbsp;Audio&nbsp;&nbsp;</label>#(/searchaudio)#
#(searchvideo)#::<label><input type="radio" id="video" name="contentdom" value="video" #(check)#::checked="checked"#(/check)# />&nbsp;Video&nbsp;&nbsp;</label>#(/searchvideo)#
#(searchapp)#::<label><input type="radio" id="app" name="contentdom" value="app" #(check)#::checked="checked"#(/check)# />&nbsp;Applications</label>#(/searchapp)#
#(searchoptions)#&nbsp;&nbsp;<a href="index.html?searchoptions=1#(authSearch)#::&auth#(/authSearch)#" onclick="this.href='index.html?searchoptions=1#(authSearch)#::&auth#(/authSearch)#&amp;former='+document.getElementById('search').value+'&amp;contentdom='+radioValue(document.getElementById('searchform').contentdom);">more options...</a>::#(/searchoptions)#
#(searchoptions)#&nbsp;&nbsp;<a href="index.html?searchoptions=1#(authSearch)#::&auth#(/authSearch)#" onclick="this.href='index.html?searchoptions=1#(authSearch)#::&auth#(/authSearch)#&amp;former='+encodeURIComponent(document.getElementById('search').value)+'&amp;contentdom='+radioValue(document.getElementById('searchform').contentdom);">more options...</a>::#(/searchoptions)#
</div>
#(/searchdomswitches)#
<input type="hidden" name="nav" value="#[search.navigation]#" />

View File

@ -325,7 +325,7 @@ public class yacysearchitem {
prop.put("content_showMetadata_urlhash", urlhash);
prop.put("content_showParser_urlhash", urlhash);
prop.put("content_showCitation_urlhash", urlhash);
prop.putHTML("content_showPictures_former", origQ);
prop.putUrlEncodedHTML("content_showPictures_former", origQ);
prop.put("content_showCache_link", resultUrlstring);
prop.put("content_showProxy_link", resultUrlstring);
prop.put("content_showHostBrowser_link", resultUrlstring);
@ -387,11 +387,16 @@ public class yacysearchitem {
prop.putHTML("content_subject", result.dc_subject());
final Iterator<String> query = theSearch.query.getQueryGoal().getIncludeStrings();
final StringBuilder s = new StringBuilder(theSearch.query.getQueryGoal().getIncludeSize() * 20);
while (query.hasNext()) s.append('+').append(query.next());
final String words = (s.length() > 0) ? s.substring(1) : "";
prop.putHTML("content_words", words);
prop.putHTML("content_showParser_words", words);
prop.putHTML("content_former", origQ);
while (query.hasNext()) {
if(s.length() > 0) {
s.append(' ');
}
s.append(query.next());
}
final String words = MultiProtocolURL.escape(s.toString()).toString();
prop.putUrlEncodedHTML("content_words", words);
prop.putUrlEncodedHTML("content_showParser_words", words);
prop.putUrlEncodedHTML("content_former", origQ);
final TextSnippet snippet = result.textSnippet();
final String desc = (snippet == null) ? "" : snippet.descriptionline(theSearch.query.getQueryGoal());
prop.put("content_description", desc);

View File

@ -156,7 +156,7 @@ public class yacysearchtrailer {
count = entry.getValue();
prop.put(fileType, "nav-topics_element_" + i + "_modifier", name);
prop.put(fileType, "nav-topics_element_" + i + "_name", name);
prop.put(fileType, "nav-topics_element_" + i + "_url", QueryParams
prop.putUrlEncoded(fileType, "nav-topics_element_" + i + "_url", QueryParams
.navurl(fileType, 0, theSearch.query, name, false, authenticated).toString());
prop.put("nav-topics_element_" + i + "_count", count);
int fontsize = TOPWORDS_MINSIZE + (TOPWORDS_MAXSIZE - TOPWORDS_MINSIZE) * (count - mincount) / (1 + maxcount - mincount);
@ -212,7 +212,7 @@ public class yacysearchtrailer {
}
prop.put(fileType, "nav-protocols_element_" + i + "_name", name);
prop.put("nav-protocols_element_" + i + "_onclick_url", url);
prop.put(fileType, "nav-protocols_element_" + i + "_url", url);
prop.putUrlEncoded(fileType, "nav-protocols_element_" + i + "_url", url);
prop.put("nav-protocols_element_" + i + "_count", count);
prop.put("nav-protocols_element_" + i + "_nl", 1);
i++;
@ -314,7 +314,7 @@ public class yacysearchtrailer {
navUrl = QueryParams.navUrlWithSingleModifierRemoved(fileType, 0, theSearch.query, rawNav, authenticated);
}
prop.put(fileType, "nav-vocabulary_" + navvoccount + "_element_" + i + "_name", name);
prop.put(fileType, "nav-vocabulary_" + navvoccount + "_element_" + i + "_url", navUrl);
prop.putUrlEncoded(fileType, "nav-vocabulary_" + navvoccount + "_element_" + i + "_url", navUrl);
prop.put(fileType, "nav-vocabulary_" + navvoccount + "_element_" + i + "_id", "vocabulary_" + navname + "_" + i);
prop.put("nav-vocabulary_" + navvoccount + "_element_" + i + "_count", count);
prop.put("nav-vocabulary_" + navvoccount + "_element_" + i + "_nl", 1);
@ -376,7 +376,7 @@ public class yacysearchtrailer {
authenticated);
}
prop.put(fileType, "navs_" + ni + "_element_" + i + "_name", navi.getElementDisplayName(name));
prop.put(fileType, "navs_" + ni + "_element_" + i + "_url", navUrl);
prop.putUrlEncoded(fileType, "navs_" + ni + "_element_" + i + "_url", navUrl);
prop.put(fileType, "navs_" + ni + "_element_" + i + "_id", naviname + "_" + i);
prop.put("navs_" + ni + "_element_" + i + "_count", count);
prop.put("navs_" + ni + "_element_" + i + "_nl", 1);
@ -419,7 +419,7 @@ public class yacysearchtrailer {
final String query = theSearch.query.getQueryGoal().getQueryString(false);
prop.put(fileType, "cat-location_query", query);
final String queryenc = theSearch.query.getQueryGoal().getQueryString(true).replace(' ', '+');
prop.put(fileType, "cat-location_queryenc", queryenc);
prop.putUrlEncoded(fileType, "cat-location_queryenc", queryenc);
}
prop.put("num-results_totalcount", theSearch.getResultCount());
EventTracker.update(EventTracker.EClass.SEARCH, new ProfilingGraph.EventSearch(theSearch.query.id(true), SearchEventType.FINALIZATION, "bottomline", 0, 0), false);

View File

@ -302,10 +302,30 @@ public class serverObjects implements Serializable, Cloneable {
put(key, value == null ? "" : CharacterCoding.unicode2html(UTF8.decodeURL(value), true));
}
/**
* Add a String UTF-8 encoded bytes to the map. The content of the string is first decoded to removed any URL encoding (application/x-www-form-urlencoded).
* Then the content of the String is escaped to be usable in HTML output.
* @param key key name as String.
* @param value the UTF-8 encoded byte array of a String that will be reencoded for HTML output.
* @see CharacterCoding#encodeUnicode2html(String, boolean)
*/
public void putHTML(final String key, final byte[] value) {
putHTML(key, value == null ? "" : UTF8.String(value));
}
/**
* Add a String to the map. The eventual URL encoding
* (application/x-www-form-urlencoded) is retained, but the String is still
* escaped to be usable in HTML output.
*
* @param key key name as String.
* @param value a String that will be reencoded for HTML output.
* @see CharacterCoding#encodeUnicode2html(String, boolean)
*/
public void putUrlEncodedHTML(final String key, final String value) {
put(key, value == null ? "" : CharacterCoding.unicode2html(value, true));
}
/**
* Like {@link #putHTML(String, String)} but takes an extra argument defining, if the returned
* String should be used in normal HTML: <code>false</code>.
@ -317,11 +337,10 @@ public class serverObjects implements Serializable, Cloneable {
}
/**
* put the key/value pair with a special method according to the given file type
* @param fileType
* Put the key/value pair, escaping characters depending on the target fileType. When the target is HTML, the content of the string is first decoded to removed any URL encoding (application/x-www-form-urlencoded).
* @param fileType the response target file type
* @param key
* @param value
* @return
*/
public void put(final RequestHeader.FileType fileType, final String key, final String value) {
if (fileType == FileType.JSON) putJSON(key, value == null ? "" : value);
@ -329,6 +348,24 @@ public class serverObjects implements Serializable, Cloneable {
else putHTML(key, value == null ? "" : value);
}
/**
* Put the key/value pair, escaping characters depending on the target fileType.
* The eventual URL encoding (application/x-www-form-urlencoded) is retained.
*
* @param fileType the response target file type
* @param key
* @param value
*/
public void putUrlEncoded(final RequestHeader.FileType fileType, final String key, final String value) {
if (fileType == FileType.JSON) {
putJSON(key, value == null ? "" : value);
} else if (fileType == FileType.XML) {
putXML(key, value == null ? "" : value);
} else {
putUrlEncodedHTML(key, value == null ? "" : value);
}
}
/**
* Add a byte/long/integer to the map. The number will be encoded into a String using
* a localized format specified by {@link Formatter} and {@link #setLocalized(boolean)}.