001c196e7f
RFC 3986 requires percent-encoding individual UTF-8 bytes. The previous implementation iterated wxUniChar code points, producing incorrect output for non-ASCII characters (e.g. é became %E9 instead of %C3%A9, and multi-byte characters like emoji produced invalid percent-encoding with more than two hex digits).
144 lines
4.0 KiB
C++
144 lines
4.0 KiB
C++
/*
|
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
|
*
|
|
* Copyright The KiCad Developers, see AUTHORS.txt for contributors.
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License as published by the
|
|
* Free Software Foundation; either version 3 of the License, or (at your
|
|
* option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along
|
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include <remote_provider_utils.h>
|
|
|
|
#include <wx/intl.h>
|
|
#include <wx/uri.h>
|
|
|
|
|
|
wxString UrlEncode( const wxString& aValue )
|
|
{
|
|
wxString encoded;
|
|
const wxScopedCharBuffer utf8 = aValue.ToUTF8();
|
|
const char* p = utf8.data();
|
|
size_t len = utf8.length();
|
|
|
|
for( size_t i = 0; i < len; ++i )
|
|
{
|
|
unsigned char byte = static_cast<unsigned char>( p[i] );
|
|
|
|
if( ( byte >= 'A' && byte <= 'Z' ) || ( byte >= 'a' && byte <= 'z' )
|
|
|| ( byte >= '0' && byte <= '9' ) || byte == '-' || byte == '_'
|
|
|| byte == '.' || byte == '~' )
|
|
{
|
|
encoded.Append( static_cast<char>( byte ) );
|
|
}
|
|
else
|
|
{
|
|
encoded.Append( wxString::Format( wxS( "%%%02X" ), byte ) );
|
|
}
|
|
}
|
|
|
|
return encoded;
|
|
}
|
|
|
|
|
|
wxString RemoteProviderJsonString( const nlohmann::json& aObject, const char* aKey )
|
|
{
|
|
auto it = aObject.find( aKey );
|
|
|
|
if( it != aObject.end() && it->is_string() )
|
|
return wxString::FromUTF8( it->get_ref<const std::string&>().c_str() );
|
|
|
|
return wxString();
|
|
}
|
|
|
|
|
|
bool IsLoopbackHost( const wxString& aHost )
|
|
{
|
|
wxString host = aHost.Lower();
|
|
|
|
if( host.StartsWith( wxS( "[" ) ) && host.EndsWith( wxS( "]" ) ) )
|
|
{
|
|
host.RemoveLast();
|
|
host.Remove( 0, 1 );
|
|
}
|
|
|
|
return host == wxS( "localhost" ) || host == wxS( "127.0.0.1" ) || host == wxS( "::1" );
|
|
}
|
|
|
|
|
|
bool ValidateRemoteUrlSecurity( const wxString& aUrl, bool aAllowInsecureLocalhost,
|
|
wxString& aError, const wxString& aLabel )
|
|
{
|
|
if( aUrl.IsEmpty() )
|
|
return true;
|
|
|
|
wxURI uri( aUrl );
|
|
wxString scheme = uri.GetScheme().Lower();
|
|
|
|
if( scheme == wxS( "https" ) )
|
|
return true;
|
|
|
|
if( scheme == wxS( "http" ) && aAllowInsecureLocalhost && IsLoopbackHost( uri.GetServer() ) )
|
|
return true;
|
|
|
|
aError = wxString::Format(
|
|
_( "%s must use HTTPS unless allow_insecure_localhost is enabled for a loopback URL." ),
|
|
aLabel );
|
|
return false;
|
|
}
|
|
|
|
|
|
wxString NormalizedUrlOrigin( const wxString& aUrl )
|
|
{
|
|
if( aUrl.IsEmpty() )
|
|
return wxString();
|
|
|
|
wxURI uri( aUrl );
|
|
|
|
if( !uri.HasScheme() || !uri.HasServer() )
|
|
return wxString();
|
|
|
|
wxString scheme = uri.GetScheme().Lower();
|
|
wxString host = uri.GetServer().Lower();
|
|
wxString port = uri.GetPort();
|
|
|
|
if( port.IsEmpty() )
|
|
{
|
|
if( scheme == wxS( "https" ) )
|
|
port = wxS( "443" );
|
|
else if( scheme == wxS( "http" ) )
|
|
port = wxS( "80" );
|
|
}
|
|
|
|
return scheme + wxS( "://" ) + host + wxS( ":" ) + port;
|
|
}
|
|
|
|
|
|
void COLLECTING_JSON_ERROR_HANDLER::error( const nlohmann::json::json_pointer& aPointer,
|
|
const nlohmann::json& aInstance,
|
|
const std::string& aMessage )
|
|
{
|
|
wxUnusedVar( aInstance );
|
|
m_errors.emplace_back( wxString::Format( wxS( "%s: %s" ),
|
|
wxString::FromUTF8( aPointer.to_string().c_str() ),
|
|
wxString::FromUTF8( aMessage.c_str() ) ) );
|
|
}
|
|
|
|
|
|
wxString COLLECTING_JSON_ERROR_HANDLER::FirstError() const
|
|
{
|
|
if( m_errors.empty() )
|
|
return wxString();
|
|
|
|
return m_errors.front();
|
|
}
|