Skip to content

inconsistent URL encoding/decoding with WMS sources  #59143

Description

@cioddi

What is the bug or the crash?

QGIS improperly encodes/decodes data source URLs, including URL parameter values, causing the original values to be altered and leading to data loss. Additionally, QgsDataSourceUri does not fully URL-encode the values when assembling the data source string leading to potential data loss.

When constructing a QgsDataSourceUri, parameter values are not fully URL-encoded. In this case only the =is encoded to %26. This can result in incorrect URL parameters being sent in the requests. For example:

  • Original URL added as WMS source:
    https://127.0.0.1/%26%3F%26%3F/?non_standard_param=%26%3F%26%3F%26%3F

  • Resulting QgsDataSourceUri string:
    dpiMode=7&featureCount=10&tilePixelRatio=0&url=https://127.0.0.1/%26%3F%26%3F/?non_standard_param%3D%26%3F%26%3F%26%3F

  • Actual GetCapabilities Request Sent:
    https://127.0.0.1/&?&?/?non_standard_param=&?&?&?SERVICE=WMS&REQUEST=GetCapabilities

Expected behaviour

  • Original URL added as WMS source:
    https://127.0.0.1/%26%3F%26%3F/?non_standard_param=%26%3F%26%3F%26%3F

  • Resulting QgsDataSourceUri string (values are fully URL-encoded:
    dpiMode=7&featureCount=10&tilePixelRatio=0&url=https%3A%2F%2F127.0.0.1%2F%2526%253F%2526%253F%2F%3Fnon_standard_param%3D%2526%253F%2526%253F%2526%253F

  • Actual GetCapabilities Request Sent:
    https://127.0.0.1/%26%3F%26%3F/?non_standard_param=%26%3F%26%3F%26%3F&SERVICE=WMS&REQUEST=GetCapabilities

Steps to reproduce the issue

  1. open QGIS and the request debug console
  2. add a WMS data source with the URL https://127.0.0.1/%26%3F%26%3F/?non_standard_param=%26%3F%26%3F%26%3F
  • in qgsnewhttpconnection.cpp (363) QUrl decodes some of the URL-encoded characters resulting in https://127.0.0.1/%26?%26?/
    QUrl url( txtUrl->text().trimmed() );
  • in qgsnewhttpconnection.cpp (381) the QUrl query is set to non_standard_param=%26%3F%26%3F%26%3F
    url.setQuery( query );
  • in qgsowsconnection.cpp (87) the QgsDataSourceUri param "url" is set to the original url https://127.0.0.1/%26%3F%26%3F/?non_standard_param=%26%3F%26%3F%26%3F resulting in the param value
    mUri.setParam( QStringLiteral( "url" ), url );
  1. right click the new WMS data source and click refresh
  • in qgswmsdataitems.cpp (61) the QgsDataSourceUri is parsed. mUri has the value dpiMode=7&featureCount=10&tilePixelRatio=0&url=https://127.0.0.1/%26%3F%26%3F/?non_standard_param%3D%26%3F%26%3F%26%3F. The key-value separator "=" has been URL-encoded to %3D the other character left untouched making it impossible to retain the original URL. The "url" param of uri becomes https://127.0.0.1/&%3F&%3F/?non_standard_param=&%3F&%3F&%3F resulting in an empty value for non_standard_param.
    uri.setEncodedUri( mUri );
  • in qgswmsprovider.cpp (280) the whole thing is URL-decoded resulting in https://127.0.0.1/&?&?/?non_standard_param=&?&?&?
    // some services provide a percent/url encoded (legend) uri string, always decode here
    uri = QUrl::fromPercentEncoding( uri.toUtf8() );
    
  1. the GetCapabilities request is made to https://127.0.0.1/&?&?/?non_standard_param=&?&?&?SERVICE=WMS&REQUEST=GetCapabilities
  • qgswmscapabilities.cpp (2559) QNetworkRequest request( url );

Versions

QGIS 3.38.3 (probably all previous versions since QgsDataSourceUri was added and used for non database providers)
Master

Supported QGIS version

  • I'm running a supported QGIS version according to the roadmap.

New profile

Additional context

Related Issues:

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugEither a bug report, or a bug fix. Let's hope for the latter!WMS data provider

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions