| 9 | #include "fl/stl/static_assert.h" |
| 10 | |
| 11 | FL_TEST_FILE(FL_FILEPATH) { |
| 12 | |
| 13 | using namespace fl; |
| 14 | |
| 15 | // ----------------------------------------------------------------------------- |
| 16 | // Compile-time: path_has_parent_segment rejects ".." segments but allows |
| 17 | // innocent-looking paths that merely contain dot characters. |
| 18 | // ----------------------------------------------------------------------------- |
| 19 | |
| 20 | FL_STATIC_ASSERT(!fl::asset_detail::path_has_parent_segment("data/track.mp3"), |
| 21 | "plain relative path should not be flagged"); |
| 22 | FL_STATIC_ASSERT(!fl::asset_detail::path_has_parent_segment("track.mp3"), |
| 23 | "bare file should not be flagged"); |
| 24 | FL_STATIC_ASSERT(!fl::asset_detail::path_has_parent_segment("folder.with.dots/a.mp3"), |
| 25 | "dots inside segments must not trigger false positive"); |
| 26 | FL_STATIC_ASSERT(!fl::asset_detail::path_has_parent_segment("."), |
| 27 | "single dot is not a parent segment"); |
| 28 | FL_STATIC_ASSERT(!fl::asset_detail::path_has_parent_segment(""), |
| 29 | "empty path is not a parent segment"); |
| 30 | |
| 31 | FL_STATIC_ASSERT(fl::asset_detail::path_has_parent_segment(".."), |
| 32 | "bare .. must be rejected"); |
| 33 | FL_STATIC_ASSERT(fl::asset_detail::path_has_parent_segment("../foo"), |
| 34 | "leading .. must be rejected"); |
| 35 | FL_STATIC_ASSERT(fl::asset_detail::path_has_parent_segment("foo/.."), |
| 36 | "trailing .. must be rejected"); |
| 37 | FL_STATIC_ASSERT(fl::asset_detail::path_has_parent_segment("data/../foo.mp3"), |
| 38 | "embedded .. must be rejected"); |
| 39 | FL_STATIC_ASSERT(fl::asset_detail::path_has_parent_segment("a/b/../c"), |
| 40 | "deep embedded .. must be rejected"); |
| 41 | // Windows-style separators are treated the same. |
| 42 | FL_STATIC_ASSERT(fl::asset_detail::path_has_parent_segment("data\\..\\foo.mp3"), |
| 43 | "backslash-style .. must also be rejected"); |
| 44 | |
| 45 | // FL_ASSET() macro returns a valid handle at compile time when the path is OK. |
| 46 | // The static_assert inside FL_ASSET fires only for ".." paths so this compiles. |
| 47 | FL_TEST_CASE("fl::asset - FL_ASSET macro produces a valid handle") { |
| 48 | asset_ref r = FL_ASSET("data/track.mp3"); |
| 49 | FL_CHECK(bool(r)); |
| 50 | FL_CHECK_EQ(r.path(), string_view("data/track.mp3")); |
| 51 | FL_CHECK_EQ(r.size(), string_view("data/track.mp3").size()); |
| 52 | } |
| 53 | |
| 54 | // The constexpr-callable `fl::asset()` function returns an EMPTY handle when |
| 55 | // the path contains "..", giving a clean runtime miss instead of a crash. |
| 56 | FL_TEST_CASE("fl::asset - runtime path with .. produces empty handle") { |
| 57 | asset_ref bad = fl::asset("data/../etc/passwd"); |
| 58 | FL_CHECK_FALSE(bool(bad)); |
| 59 | FL_CHECK_EQ(bad.size(), 0u); |
| 60 | } |
| 61 | |
| 62 | FL_TEST_CASE("fl::asset - plain path produces non-empty handle") { |
| 63 | asset_ref r = fl::asset("data/track.mp3"); |
| 64 | FL_CHECK(bool(r)); |
| 65 | FL_CHECK_EQ(r.path(), string_view("data/track.mp3")); |
| 66 | } |
| 67 | |
| 68 | // ----------------------------------------------------------------------------- |
nothing calls this directly
no test coverage detected