From 36ffdb93e83e0f83abd760e004fa867795762bf8 Mon Sep 17 00:00:00 2001 From: Murtuza Zabuawala Date: Fri, 1 Mar 2019 14:55:25 +0000 Subject: [PATCH] Custom-encode forward slashes in URL parameters as Apache HTTPD doesn't allow them in some cases. Fixes #3998 --- docs/en_US/release_notes_4_3.rst | 1 + web/pgadmin/static/js/sqleditor_utils.js | 16 ++++++ web/pgadmin/tools/datagrid/__init__.py | 10 ++++ .../tools/datagrid/static/js/datagrid.js | 23 +++----- .../tools/datagrid/static/js/show_data.js | 4 +- .../javascript/sqleditor_utils_spec.js | 56 +++++++++++++++++++ 6 files changed, 93 insertions(+), 17 deletions(-) diff --git a/docs/en_US/release_notes_4_3.rst b/docs/en_US/release_notes_4_3.rst index bed5d4dd7..b9215bb57 100644 --- a/docs/en_US/release_notes_4_3.rst +++ b/docs/en_US/release_notes_4_3.rst @@ -45,6 +45,7 @@ Bug fixes | `Bug #3982 `_ - Add full support and testsfor all PG server side encodings. | `Bug #3985 `_ - Don't embed docs and external sites in iframes, to allow the external sites to set X-FRAME-OPTIONS = DENY for security. | `Bug #3992 `_ - Add full support and testsfor all PG server side encodings. +| `Bug #3998 `_ - Custom-encode forward slashes in URL parameters as Apache HTTPD doesn't allow them in some cases. | `Bug #4000 `_ - Update CodeMirror to 5.43.0 to resolve issues with tab indent with use spaces enabled. | `Bug #4013 `_ - Ensure long queries don't cause errors when downloading CSV in the Query Tool. | `Bug #4021 `_ - Disable the editor and execute functions whilst queries are executing. diff --git a/web/pgadmin/static/js/sqleditor_utils.js b/web/pgadmin/static/js/sqleditor_utils.js index 19ad772ec..74d8ad50e 100644 --- a/web/pgadmin/static/js/sqleditor_utils.js +++ b/web/pgadmin/static/js/sqleditor_utils.js @@ -195,6 +195,22 @@ define(['jquery', 'sources/gettext', 'sources/url_for'], } return '1em'; }, + + removeSlashInTheString: (value) => { + let locationList = []; + let idx = 0; + while (value && value.indexOf('/') !== -1) { + locationList.push(value.indexOf('/') + idx); + value = value.replace('/', ''); + // No of slashes already removed, so we need to increment the + // index accordingly when adding into location list + idx++; + } + return { + 'slashLocations': locationList.join(','), + 'title': encodeURIComponent(value), + }; + }, }; return sqlEditorUtils; }); diff --git a/web/pgadmin/tools/datagrid/__init__.py b/web/pgadmin/tools/datagrid/__init__.py index 3736e38af..778a9810a 100644 --- a/web/pgadmin/tools/datagrid/__init__.py +++ b/web/pgadmin/tools/datagrid/__init__.py @@ -230,6 +230,16 @@ def panel(trans_id, is_query_tool, editor_title): else: server_type = None + # If title has slash(es) in it then replace it + if request.args and request.args['fslashes'] != '': + try: + fslashesList = request.args['fslashes'].split(',') + for idx in fslashesList: + idx = int(idx) + editor_title = editor_title[:idx] + '/' + editor_title[idx:] + except IndexError as e: + app.logger.exception(e) + # We need client OS information to render correct Keyboard shortcuts user_agent = UserAgent(request.headers.get('User-Agent')) diff --git a/web/pgadmin/tools/datagrid/static/js/datagrid.js b/web/pgadmin/tools/datagrid/static/js/datagrid.js index 0a795faba..b4c0ea006 100644 --- a/web/pgadmin/tools/datagrid/static/js/datagrid.js +++ b/web/pgadmin/tools/datagrid/static/js/datagrid.js @@ -234,17 +234,7 @@ define('pgadmin.datagrid', [ return; } - var nsp_name = ''; - - if (parentData.schema != undefined) { - nsp_name = parentData.schema.label; - } - else if (parentData.view != undefined) { - nsp_name = parentData.view.label; - } - else if (parentData.catalog != undefined) { - nsp_name = parentData.catalog.label; - } + let nsp_name = showData.retrieveNameSpaceName(parentData); var url_params = { 'cmd_type': data.mnuid, @@ -263,8 +253,8 @@ define('pgadmin.datagrid', [ 'did': url_params['did'], 'obj_id': url_params['obj_id'], }); - var grid_title = parentData.server.label + '-' + parentData.database.label + '-' - + nsp_name + '.' + d.label; + + let grid_title = showData.generateDatagridTitle(parentData, nsp_name, d); // Create filter dialog using alertify if (!alertify.filterDialog) { @@ -481,13 +471,16 @@ define('pgadmin.datagrid', [ } // Open the panel if frame is initialized + let titileForURLObj = sqlEditorUtils.removeSlashInTheString(grid_title); var url_params = { 'trans_id': trans_obj.gridTransId, 'is_query_tool': trans_obj.is_query_tool, - 'editor_title': encodeURIComponent(grid_title), + 'editor_title': titileForURLObj.title, }, baseUrl = url_for('datagrid.panel', url_params) + - '?' + 'query_url=' + encodeURI(trans_obj.sURL) + '&server_type=' + encodeURIComponent(trans_obj.server_type); + '?' + 'query_url=' + encodeURI(trans_obj.sURL) + + '&server_type=' + encodeURIComponent(trans_obj.server_type) + + '&fslashes=' + titileForURLObj.slashLocations; if (self.preferences.new_browser_tab) { var newWin = window.open(baseUrl, '_blank'); diff --git a/web/pgadmin/tools/datagrid/static/js/show_data.js b/web/pgadmin/tools/datagrid/static/js/show_data.js index 33f0db1f0..eca275264 100644 --- a/web/pgadmin/tools/datagrid/static/js/show_data.js +++ b/web/pgadmin/tools/datagrid/static/js/show_data.js @@ -52,7 +52,7 @@ export function showDataGrid( } -function retrieveNameSpaceName(parentData) { +export function retrieveNameSpaceName(parentData) { if (parentData.schema !== undefined) { return parentData.schema.label; } @@ -87,6 +87,6 @@ function hasSchemaOrCatalogOrViewInformation(parentData) { parentData.catalog !== undefined; } -function generateDatagridTitle(parentData, namespaceName, nodeData) { +export function generateDatagridTitle(parentData, namespaceName, nodeData) { return `${namespaceName}.${nodeData.label}`; } diff --git a/web/regression/javascript/sqleditor_utils_spec.js b/web/regression/javascript/sqleditor_utils_spec.js index f2a70c0aa..76bf41e7d 100644 --- a/web/regression/javascript/sqleditor_utils_spec.js +++ b/web/regression/javascript/sqleditor_utils_spec.js @@ -36,5 +36,61 @@ function (SqlEditorUtils) { expect(SqlEditorUtils.calcFontSize(2)).toEqual('2em'); }); }); + + describe('Remove the slashes', function () { + it('it will remove the slashes', function () { + expect( + SqlEditorUtils.removeSlashInTheString('/') + ).toEqual({ + 'slashLocations': '0', + 'title': '', + }); + }); + + it('it will remove if slashes are present', function () { + expect( + SqlEditorUtils.removeSlashInTheString('my/test') + ).toEqual({ + 'slashLocations': '2', + 'title': 'mytest', + }); + }); + + it('it will remove all the slashes are present', function () { + expect( + SqlEditorUtils.removeSlashInTheString('my/test/value') + ).toEqual({ + 'slashLocations': '2,7', + 'title': 'mytestvalue', + }); + }); + + it('it will remove all the slashes are present', function () { + expect( + SqlEditorUtils.removeSlashInTheString('a/bb/ccc/dddd/eeeee') + ).toEqual({ + 'slashLocations': '1,4,8,13', + 'title': 'abbcccddddeeeee', + }); + }); + + it('it will not remove if slash is not present', function () { + expect( + SqlEditorUtils.removeSlashInTheString('mytest') + ).toEqual({ + 'slashLocations': '', + 'title': 'mytest', + }); + }); + + it('it will not remove if value is not present', function () { + expect( + SqlEditorUtils.removeSlashInTheString('') + ).toEqual({ + 'slashLocations': '', + 'title': '', + }); + }); + }); }); });