Compare commits

...
Sign in to create a new pull request.

7 commits

Author SHA1 Message Date
4e46d35845 Set correct paths for CC and CXX environment variables 2025-03-20 03:26:27 +02:00
4180c15333
Update linux-check.yaml
Signed-off-by: Raghaddahi <raghaddahi27@gmail.com>
2025-03-19 23:09:52 +02:00
2b1f9d37fc
Update linux-check.yaml
Signed-off-by: Raghaddahi <raghaddahi27@gmail.com>
2025-03-16 08:25:46 +02:00
3f5cf7008e Add setup-mock-files.sh script to create mock files 2025-03-16 08:16:40 +02:00
cafbe4aa08 [url] Fix URL class handling of invalid URLs
The current implementation incorrectly validates URLs without a host (e.g., 'https://')
and URLs with invalid schemes (e.g., '@&€:1;asf'). This change updates the URL
parsing logic to reject such URLs, ensuring that only valid URLs are accepted.

Fixes: #1566
Signed-off-by: Raghad Dahi <raghaddahi27@gmail.com>
2025-03-13 07:45:21 +02:00
d18a46ac6a Fix URL validation logic (closes #1566)
Signed-off-by: Raghad Dahi <raghaddahi27@gmail.com>
2025-03-13 07:45:21 +02:00
8766e8974a modified parse url funcation and added more url tests
Signed-off-by: Raghad Dahi <raghaddahi27@gmail.com>
2025-03-13 07:45:21 +02:00
5 changed files with 143 additions and 80 deletions

View file

@ -48,6 +48,10 @@ jobs:
with:
fetch-depth: 100 # enough to get all commits for the current day
- name: Set up environment and mock files
run: ./setup-mock-files.sh
- name: Parallel submodules checkout
shell: bash
run: git submodule update --depth 1 --init --recursive --jobs=$(($(nproc) * 20))
@ -79,8 +83,8 @@ jobs:
- name: CMake
shell: bash
env:
CC: clang-18
CXX: clang++-18
CC: /usr/bin/clang-18
CXX: /usr/bin/clang++-18
CMAKE_C_COMPILER_LAUNCHER: ccache
CMAKE_CXX_COMPILER_LAUNCHER: ccache
# -g1 should slightly reduce build time.
@ -95,7 +99,7 @@ jobs:
linux-matrix:
name: Linux builds and tests
runs-on: ubuntu-24.04
runs-on: ubuntu-22.04
strategy:
fail-fast: false
matrix:
@ -146,15 +150,14 @@ jobs:
- name: CMake
shell: bash
env:
CC: ${{ matrix.compiler.CC }}
CXX: ${{ matrix.compiler.CXX }}
CMAKE_C_COMPILER_LAUNCHER: ccache
CMAKE_CXX_COMPILER_LAUNCHER: ccache
# -g1 should slightly reduce build time.
CC: /usr/bin/${{ matrix.compiler.CC }}
CXX: /usr/bin/${{ matrix.compiler.CXX }}
CMAKE_C_COMPILER_LAUNCHER: ccache
CMAKE_CXX_COMPILER_LAUNCHER: ccache
run: |
echo "Building ${{ matrix.CMAKE_BUILD_TYPE }}"
cmake . -B build -G Ninja -DCMAKE_BUILD_TYPE=${{ matrix.CMAKE_BUILD_TYPE }} \
-DCMAKE_C_FLAGS=-g1 -DCMAKE_CXX_FLAGS=-g1
echo "Building ${{ matrix.CMAKE_BUILD_TYPE }}"
cmake . -B build -G Ninja -DCMAKE_BUILD_TYPE=${{ matrix.CMAKE_BUILD_TYPE }} \
-DCMAKE_C_FLAGS=-g1 -DCMAKE_CXX_FLAGS=-g1
- name: Compile
shell: bash

View file

@ -105,6 +105,13 @@ UNIT_TEST(Url_Invalid)
TEST(!Url("").IsValid(), ());
TEST(!Url(":/").IsValid(), ());
TEST(!Url("//").IsValid(), ());
// Updated tests for the new behavior:
TEST(!Url("scheme://").IsValid(), ());
TEST(!Url("@&€:1;asf").IsValid(), ());
TEST(!Url("123scheme:test").IsValid(), ());
TEST(!Url("scheme:").IsValid(), ());
TEST(!Url("scheme:/").IsValid(), ());
}
UNIT_TEST(Url_Valid)
@ -112,22 +119,26 @@ UNIT_TEST(Url_Valid)
TestUrl("mapswithme://map?ll=10.3,12.3223&n=Hello%20World")
.Scheme("mapswithme")
.Host("map")
.Path("")
.KV("ll", "10.3,12.3223")
.KV("n", "Hello World");
TestUrl("om:M&M//path?q=q&w=w")
TestUrl("om:M&M//path?q=q&w=w")
.Scheme("om")
.Host("M&M")
.Path("path")
.Path("path") // Expected "path" (no leading slash)
.KV("q", "q")
.KV("w", "w");
TestUrl("http://www.sandwichparlour.com.au/")
.Scheme("http")
.Host("www.sandwichparlour.com.au")
.Path("");
.Path("");
TestUrl("om:/&test").Scheme("om").Host("&test").Path("");
TestUrl("om:/&test")
.Scheme("om")
.Host("&test")
.Path("");
}
UNIT_TEST(Url_Fragment)
@ -135,7 +146,7 @@ UNIT_TEST(Url_Fragment)
TestUrl("https://www.openstreetmap.org/way/179409926#map=19/46.34998/48.03213&layers=N")
.Scheme("https")
.Host("www.openstreetmap.org")
.Path("way/179409926")
.Path("way/179409926") // Expected to be relative (without leading slash)
.KV("map", "19/46.34998/48.03213")
.KV("layers", "N");
@ -150,9 +161,9 @@ UNIT_TEST(Url_Fragment)
UNIT_TEST(UrlScheme_Comprehensive)
{
TestUrl("");
TestUrl("scheme:").Scheme("scheme").Host("").Path("");
TestUrl("scheme:/").Scheme("scheme").Host("").Path("");
TestUrl("scheme://").Scheme("scheme").Host("").Path("");
TestUrl("scheme:host").Scheme("scheme").Host("host").Path("");
TestUrl("scheme:/host").Scheme("scheme").Host("host").Path("");
TestUrl("scheme://host").Scheme("scheme").Host("host").Path("");
TestUrl("sometext");
TestUrl(":noscheme");
TestUrl("://noscheme?");
@ -189,4 +200,4 @@ UNIT_TEST(UrlApi_Smoke)
TEST(url.GetParamValue("m"), ());
}
} // namespace url_tests
} // namespace url_tests

View file

@ -25,76 +25,104 @@ Url Url::FromString(std::string const & url)
bool Url::Parse(std::string const & url)
{
// Get url scheme.
size_t start = url.find(':');
if (start == string::npos || start == 0)
return false;
// Get url scheme.
size_t start = url.find(':');
if (start == string::npos || !isalpha(url[0]))
{
return false;
}
if (start + 1 == url.size())
{
return false;
}
//validate scheme
for (size_t i = 1; i < start; ++i)
{
char c = url[i];
if (!(isalnum(c) || c == '+' || c == '.' || c == '-'))
return false;
}
m_scheme = url.substr(0, start);
// Skip slashes.
start = url.find_first_not_of('/', start + 1);
if (start == std::string::npos)
return true;
// Skip slashes.
start = url.find_first_not_of('/', start + 1);
if (start == std::string::npos)
{
return false; // This correctly rejects "scheme://" with nothing after it
}
// Get host.
size_t end = url.find_first_of("/?#", start);
if (end == string::npos)
{
m_host = url.substr(start);
return true;
}
else
m_host = url.substr(start, end - start);
// Get path.
if (url[end] == '/')
{
// Skip slashes.
start = url.find_first_not_of('/', end);
if (start == std::string::npos)
return true;
// Check if there's a host or just a path.
size_t end = url.find_first_of("/?#", start);
if (end == start) // prevent cases like: "scheme:///"
return false;
else if (end == std::string::npos)
{
m_host = url.substr(start);
if (m_host.empty())
return false;
return true;
}
else
{
m_host = url.substr(start, end - start);
if (m_host.empty()) // Ensure the host is not empty
return false;
}
end = url.find_first_of("?#", start);
if (end == string::npos)
{
m_path = url.substr(start);
return true;
}
else
m_path = url.substr(start, end - start);
}
// Get path.
if (url[end] == '/')
{
// Skip slashes.
start = url.find_first_not_of('/', end);
if (start == std::string::npos)
return true;
// Parse query/fragment for keys and values.
for (start = end + 1; start < url.size();)
{
end = url.find_first_of("&#", start);
if (end == string::npos)
end = url.size();
end = url.find_first_of("?#", start);
if (end == string::npos)
{
m_path = url.substr(start);
return true;
}
else
m_path = url.substr(start, end - start);
}
// Skip empty keys.
if (end != start)
{
size_t const eq = url.find('=', start);
// Parse query/fragment for keys and values.
for (start = end + 1; start < url.size();)
{
end = url.find_first_of("&#", start);
if (end == string::npos)
end = url.size();
string key;
string value;
if (eq != string::npos && eq < end)
{
key = UrlDecode(url.substr(start, eq - start));
value = UrlDecode(url.substr(eq + 1, end - eq - 1));
}
else
{
key = UrlDecode(url.substr(start, end - start));
}
// Skip empty keys.
if (end != start)
{
size_t const eq = url.find('=', start);
m_params.emplace_back(key, value);
}
string key;
string value;
if (eq != string::npos && eq < end)
{
key = UrlDecode(url.substr(start, eq - start));
value = UrlDecode(url.substr(eq + 1, end - eq - 1));
}
else
{
key = UrlDecode(url.substr(start, end - start));
}
start = end + 1;
}
m_params.emplace_back(key, value);
}
return true;
start = end + 1;
}
return true;
}
string Join(string const & lhs, string const & rhs)

View file

@ -18,7 +18,7 @@ public:
explicit Url(std::string const & url);
static Url FromString(std::string const & url);
bool IsValid() const { return !m_scheme.empty(); }
bool IsValid() const { return !m_scheme.empty() && !m_host.empty(); }
std::string const & GetScheme() const { return m_scheme; }
std::string const & GetHost() const { return m_host; }

21
setup-mock-files.sh Normal file
View file

@ -0,0 +1,21 @@
#!/bin/bash
# Create directories if they do not exist
mkdir -p $GITHUB_WORKSPACE/organicmaps/data/bookmarks
mkdir -p $GITHUB_WORKSPACE/organicmaps/data/test_data
mkdir -p /tmp
# Create empty mock files
touch $GITHUB_WORKSPACE/organicmaps/data/power_manager_config
touch $GITHUB_WORKSPACE/organicmaps/data/bookmarks/cat1.kmb
touch $GITHUB_WORKSPACE/organicmaps/data/bookmarks/cat2.kmb
touch $GITHUB_WORKSPACE/organicmaps/data/bookmarks/cat3.kmb
touch $GITHUB_WORKSPACE/organicmaps/data/bookmarks/Bookmarks.kmb
touch $GITHUB_WORKSPACE/organicmaps/data/bookmarks/xxx.kmb
touch $GITHUB_WORKSPACE/organicmaps/data/test_data/broken_bookmarks.kmb.test
touch $GITHUB_WORKSPACE/organicmaps/data/gpstrack_test.bin
touch /tmp/tmp.xml
touch /tmp/Some\ random\ route.kml
touch /tmp/new.kml
touch /tmp/OrganicMaps_1.kml
touch /tmp/OrganicMaps_2.kml