// Keep in sync with FilterSetUtilsMixin.(empty_value|other_value)
if (name === "(No value detected)") name = "_EMPTY_";
if (name === "Other") name = "_OTHER_";
- let full_url = `${base_url}?${field}=${name}`;
+ let full_url = `${base_url}?${field}=${encodeURIComponent(name)}`;
if (in_package) full_url += `&in_package=${in_package}`;
if (event.ctrlKey || event.metaKey) window.open(full_url, '_blank');
else window.location.href = full_url;
diff --git a/scanpipe/templates/scanpipe/resource_list.html b/scanpipe/templates/scanpipe/resource_list.html
index 44091f4baa..6bf10b8c54 100644
--- a/scanpipe/templates/scanpipe/resource_list.html
+++ b/scanpipe/templates/scanpipe/resource_list.html
@@ -54,7 +54,7 @@
{{ resource.extension }}
|
- {{ resource.programming_language }}
+ {{ resource.programming_language }}
|
{{ resource.mime_type }}
diff --git a/scanpipe/tests/test_api.py b/scanpipe/tests/test_api.py
index 03d68cfaca..8bb5f63ef3 100644
--- a/scanpipe/tests/test_api.py
+++ b/scanpipe/tests/test_api.py
@@ -788,6 +788,18 @@ def test_scanpipe_api_project_action_resources_filterset(self):
response = self.csrf_client.get(url + "?slug=aaa")
self.assertEqual(2, response.data["count"])
+ def test_scanpipe_api_project_action_resources_filterset_special_chars(self):
+ make_resource_file(
+ self.project1,
+ path="csharp_file.cs",
+ programming_language="C#",
+ )
+ url = reverse("project-resources", args=[self.project1.uuid])
+ response = self.csrf_client.get(url + "?programming_language=C%23")
+ self.assertEqual(1, response.data["count"])
+ self.assertEqual("csharp_file.cs", response.data["results"][0]["path"])
+ self.assertEqual("C#", response.data["results"][0]["programming_language"])
+
def test_scanpipe_api_project_action_packages(self):
url = reverse("project-packages", args=[self.project1.uuid])
response = self.csrf_client.get(url)
diff --git a/scanpipe/tests/test_views.py b/scanpipe/tests/test_views.py
index 63e9b9f295..09603c5316 100644
--- a/scanpipe/tests/test_views.py
+++ b/scanpipe/tests/test_views.py
@@ -590,6 +590,18 @@ def test_scanpipe_views_project_details_scan_summary_panels(self):
self.assertContains(response, expected1)
self.assertContains(response, expected2)
+ def test_scanpipe_views_project_details_scan_summary_language_url_encoding(self):
+ summary_file = self.project1.get_output_file_path("summary", "json")
+ scan_summary_json = {
+ "primary_language": [{"value": "C#", "count": 1}],
+ "other_languages": [{"value": "C#", "count": 1}],
+ }
+ summary_file.write_text(json.dumps(scan_summary_json))
+ url = self.project1.get_absolute_url()
+ response = self.client.get(url)
+ self.assertContains(response, "?programming_language=C%23")
+ self.assertNotContains(response, "?programming_language=C#")
+
def test_scanpipe_views_project_details_get_license_clarity_data(self):
get_license_clarity_data = ProjectDetailView.get_license_clarity_data
@@ -1039,6 +1051,17 @@ def test_scanpipe_views_codebase_resource_list_view_bad_search_query(self):
expected_error = "The provided search value is invalid: No closing quotation"
self.assertContains(response, expected_error)
+ def test_scanpipe_views_codebase_resource_list_programming_language_url_encoding(
+ self,
+ ):
+ make_resource_file(
+ self.project1, path="csharp_file.cs", programming_language="C#"
+ )
+ url = reverse("project_resources", args=[self.project1.slug])
+ response = self.client.get(url)
+ self.assertContains(response, "?programming_language=C%23")
+ self.assertNotContains(response, "?programming_language=C#")
+
def test_scanpipe_views_codebase_resource_details_view_tab_image(self):
resource1 = make_resource_file(self.project1, "file1.ext")
response = self.client.get(resource1.get_absolute_url())
|