mirror of
https://github.com/microsoft/terminal.git
synced 2026-04-09 15:51:05 +00:00
Disallow certain non-filename characters in Export Text (#13693)
Added control in code for not allowed characters in the filename when saving a
tab.
Closes #13664
(cherry picked from commit 8721573957)
Service-Card-Id: 85487287
Service-Version: 1.15
This commit is contained in:
committed by
Dustin Howett
parent
377cc05fb7
commit
d1c7ee2c17
@@ -12,6 +12,7 @@
|
||||
#include "TerminalPage.h"
|
||||
#include "Utils.h"
|
||||
#include "../../types/inc/utils.hpp"
|
||||
#include "../../inc/til/string.h"
|
||||
|
||||
#include <LibraryResources.h>
|
||||
|
||||
@@ -392,6 +393,7 @@ namespace winrt::TerminalApp::implementation
|
||||
THROW_IF_FAILED(dialog->SetDefaultExtension(L"txt"));
|
||||
|
||||
// Default to using the tab title as the file name
|
||||
filename = til::clean_filename(filename);
|
||||
THROW_IF_FAILED(dialog->SetFileName((filename + L".txt").c_str()));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -30,6 +30,29 @@ namespace til // Terminal Implementation Library. Also: "Today I Learned"
|
||||
return visualize_control_codes(std::wstring{ str });
|
||||
}
|
||||
|
||||
_TIL_INLINEPREFIX std::wstring clean_filename(std::wstring str) noexcept
|
||||
{
|
||||
static constexpr std::array<bool, 128> filter{ {
|
||||
// clang-format off
|
||||
0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */, 0 /* EOT */, 0 /* ENQ */, 0 /* ACK */, 0 /* BEL */, 0 /* BS */, 0 /* HT */, 0 /* LF */, 0 /* VT */, 0 /* FF */, 0 /* CR */, 0 /* SO */, 0 /* SI */,
|
||||
0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */, 0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */, 0 /* CAN */, 0 /* EM */, 0 /* SUB */, 0 /* ESC */, 0 /* FS */, 0 /* GS */, 0 /* RS */, 0 /* US */,
|
||||
0 /* SP */, 0 /* ! */, 1 /* " */, 0 /* # */, 0 /* $ */, 0 /* % */, 0 /* & */, 0 /* ' */, 0 /* ( */, 0 /* ) */, 1 /* * */, 0 /* + */, 0 /* , */, 0 /* - */, 0 /* . */, 1 /* / */,
|
||||
0 /* 0 */, 0 /* 1 */, 0 /* 2 */, 0 /* 3 */, 0 /* 4 */, 0 /* 5 */, 0 /* 6 */, 0 /* 7 */, 0 /* 8 */, 0 /* 9 */, 1 /* : */, 0 /* ; */, 1 /* < */, 0 /* = */, 1 /* > */, 1 /* ? */,
|
||||
0 /* @ */, 0 /* A */, 0 /* B */, 0 /* C */, 0 /* D */, 0 /* E */, 0 /* F */, 0 /* G */, 0 /* H */, 0 /* I */, 0 /* J */, 0 /* K */, 0 /* L */, 0 /* M */, 0 /* N */, 0 /* O */,
|
||||
0 /* P */, 0 /* Q */, 0 /* R */, 0 /* S */, 0 /* T */, 0 /* U */, 0 /* V */, 0 /* W */, 0 /* X */, 0 /* Y */, 0 /* Z */, 0 /* [ */, 1 /* \ */, 0 /* ] */, 0 /* ^ */, 0 /* _ */,
|
||||
0 /* ` */, 0 /* a */, 0 /* b */, 0 /* c */, 0 /* d */, 0 /* e */, 0 /* f */, 0 /* g */, 0 /* h */, 0 /* i */, 0 /* j */, 0 /* k */, 0 /* l */, 0 /* m */, 0 /* n */, 0 /* o */,
|
||||
0 /* p */, 0 /* q */, 0 /* r */, 0 /* s */, 0 /* t */, 0 /* u */, 0 /* v */, 0 /* w */, 0 /* x */, 0 /* y */, 0 /* z */, 0 /* { */, 1 /* | */, 0 /* } */, 0 /* ~ */, 0 /* DEL */,
|
||||
// clang-format on
|
||||
} };
|
||||
|
||||
str.erase(std::remove_if(std::begin(str), std::end(str), [](auto ch) {
|
||||
// This lookup is branchless: It always checks the filter, but throws
|
||||
// away the result if ch >= 128. This is faster than using `&&` (branchy).
|
||||
return til::at(filter, ch & 127) & (ch < 128);
|
||||
}), str.end());
|
||||
return str;
|
||||
}
|
||||
|
||||
// std::string_view::starts_with support for C++17.
|
||||
template<typename T, typename Traits>
|
||||
constexpr bool starts_with(const std::basic_string_view<T, Traits>& str, const std::basic_string_view<T, Traits>& prefix) noexcept
|
||||
|
||||
@@ -169,4 +169,9 @@ class StringTests
|
||||
VERIFY_ARE_EQUAL("", s);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_METHOD(CleanPathAndFilename)
|
||||
{
|
||||
VERIFY_ARE_EQUAL(LR"(CUsersGeddyMusicAnalog Man)", til::clean_filename(LR"(C:\Users\Geddy\Music\"Analog Man")"));
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user