Repository: microsoft/terminal
File: src/cascadia/TerminalApp/ShortcutActionDispatch.cpp (C++)

Code before:
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

#include "pch.h"
#include "ShortcutActionDispatch.h"

#include "ShortcutActionDispatch.g.cpp"

using namespace winrt::Microsoft::Terminal;
using namespace winrt::Microsoft::Terminal::Settings::Model;
using namespace winrt::TerminalApp;

#define ACTION_CASE(action)              \
    case ShortcutAction::action:         \
    {                                    \
        action.raise(sender, eventArgs); \
        break;                           \
    }

namespace winrt::TerminalApp::implementation
{
    std::wstring ExtractAction(const ActionAndArgs& actionAndArgs)
    {
        // Formatted as "User.{action}" or "User.{action}.{hash}"
        std::wstring_view remaining{ actionAndArgs.GenerateID() };

        // Throw away "User."
        std::ignore = til::prefix_split(remaining, L'.');

        // Get the "{action}" part
        const auto actionName = til::prefix_split(remaining, L'.');
        return std::wstring{ actionName };
    }

    // Method Description:
    // - Dispatch the appropriate event for the given ActionAndArgs. Constructs
    //   an ActionEventArgs to hold the IActionArgs payload for the event, and
    //   calls the matching handlers for that event.
    // Arguments:
    // - actionAndArgs: the ShortcutAction and associated args to raise an event for.
    // Return Value:
    // - true if we handled the event was handled, else false.
    bool ShortcutActionDispatch::DoAction(const winrt::Windows::Foundation::IInspectable& sender,
                                          const ActionAndArgs& actionAndArgs)
    {
        if (!actionAndArgs)
        {
            return false;
        }


Review comment (suggestion):
This is unsafe, because string-views never hold onto the memory. They're just a view into someone else's container after all. Simply assign the return value from `GenerateID()` to a separate variable, which will ensure that the `hstring` is kept alive.

Code after:
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

#include "pch.h"
#include "ShortcutActionDispatch.h"

#include "ShortcutActionDispatch.g.cpp"

using namespace winrt::Microsoft::Terminal;
using namespace winrt::Microsoft::Terminal::Settings::Model;
using namespace winrt::TerminalApp;

#define ACTION_CASE(action)              \
    case ShortcutAction::action:         \
    {                                    \
        action.raise(sender, eventArgs); \
        break;                           \
    }

namespace winrt::TerminalApp::implementation
{
    // Method Description:
    // - Dispatch the appropriate event for the given ActionAndArgs. Constructs
    //   an ActionEventArgs to hold the IActionArgs payload for the event, and
    //   calls the matching handlers for that event.
    // Arguments:
    // - actionAndArgs: the ShortcutAction and associated args to raise an event for.
    // Return Value:
    // - true if we handled the event was handled, else false.
    bool ShortcutActionDispatch::DoAction(const winrt::Windows::Foundation::IInspectable& sender,
                                          const ActionAndArgs& actionAndArgs)
    {
        if (!actionAndArgs)
        {
            return false;
        }

        const auto& action = actionAndArgs.Action();
        const auto& args = actionAndArgs.Args();
        auto eventArgs = args ? ActionEventArgs{ args } :
                                ActionEventArgs{};

        switch (action)
        {
#define ON_ALL_ACTIONS(id) ACTION_CASE(id);
            ALL_SHORTCUT_ACTIONS
            INTERNAL_SHORTCUT_ACTIONS
#undef ON_ALL_ACTIONS
        default:
            return false;