Repository: microsoft/terminal
File: src/buffer/out/textBuffer.cpp (C++)

Code before:
                    // |aaaaaaaaaaaaaaaaaaa| and show a wrap at the end
                    // |                   |
                    //  ^ and the cursor is now there.
                    // If we leave it like this, we've lost the newline information.
                    // So we insert one more newline so a continued reflow of this buffer by resizing larger will
                    // continue to look as the original output intended with the newline data.
                    // After this fix, it looks like this:
                    // |aaaaaaaaaaaaaaaaaaa| no wrap at the end (preserved hard newline)
                    // |                   |
                    //  ^ and the cursor is now here.
                    const COORD coordNewCursor = newCursor.GetPosition();
                    if (coordNewCursor.X == 0 && coordNewCursor.Y > 0)
                    {
                        if (newBuffer.GetRowByOffset(gsl::narrow_cast<size_t>(coordNewCursor.Y) - 1).WasWrapForced())
                        {
                            hr = newBuffer.NewlineCursor() ? hr : E_OUTOFMEMORY;
                        }
                    }
                }
            }
        }
    }

    // Finish copying buffer attributes to remaining rows below the last
    // printable character. This is to fix the `color 2f` scenario, where you
    // change the buffer colors then resize and everything below the past
    // printable char gets reset. See GH #12567
    auto newRowY = newCursor.GetPosition().Y + 1;
    const auto newHeight = newBuffer.GetSize().Height();
    const auto oldHeight = oldBuffer.GetSize().Height();
    for (;
         iOldRow < oldHeight && newRowY < newHeight;
         iOldRow++)
    {
        const ROW& row = oldBuffer.GetRowByOffset(iOldRow);

        // Optimization: Since all these rows are below the last printable char,
        // we can reasonably assume that they are filled with just spaces.
        // That's convenient, we can just copy the attr row from the old buffer
        // into the new one, and resize the row to match. We'll rely on the
        // behavior of ATTR_ROW::Resize to trim down when narrower, or extend
        // the last attr when wider.
        auto& newRow = newBuffer.GetRowByOffset(newRowY);
        const auto newWidth = newBuffer.GetLineWidth(newRowY);
        newRow.GetAttrRow() = row.GetAttrRow();
        newRow.GetAttrRow().Resize(newWidth);

        newRowY++;
    }

    if (SUCCEEDED(hr))

Review comment (suggestion):
```suggestion
    // change the buffer colors then resize and everything below the last
```

Code after:
                    // |aaaaaaaaaaaaaaaaaaa| and show a wrap at the end
                    // |                   |
                    //  ^ and the cursor is now there.
                    // If we leave it like this, we've lost the newline information.
                    // So we insert one more newline so a continued reflow of this buffer by resizing larger will
                    // continue to look as the original output intended with the newline data.
                    // After this fix, it looks like this:
                    // |aaaaaaaaaaaaaaaaaaa| no wrap at the end (preserved hard newline)
                    // |                   |
                    //  ^ and the cursor is now here.
                    const COORD coordNewCursor = newCursor.GetPosition();
                    if (coordNewCursor.X == 0 && coordNewCursor.Y > 0)
                    {
                        if (newBuffer.GetRowByOffset(gsl::narrow_cast<size_t>(coordNewCursor.Y) - 1).WasWrapForced())
                        {
                            hr = newBuffer.NewlineCursor() ? hr : E_OUTOFMEMORY;
                        }
                    }
                }
            }
        }
    }

    // Finish copying buffer attributes to remaining rows below the last
    // printable character. This is to fix the `color 2f` scenario, where you
    // change the buffer colors then resize and everything below the last
    // printable char gets reset. See GH #12567
    auto newRowY = newCursor.GetPosition().Y + 1;
    const auto newHeight = newBuffer.GetSize().Height();
    const auto oldHeight = oldBuffer.GetSize().Height();
    for (;
         iOldRow < oldHeight && newRowY < newHeight;
         iOldRow++)
    {
        const ROW& row = oldBuffer.GetRowByOffset(iOldRow);

        // Optimization: Since all these rows are below the last printable char,
        // we can reasonably assume that they are filled with just spaces.
        // That's convenient, we can just copy the attr row from the old buffer
        // into the new one, and resize the row to match. We'll rely on the
        // behavior of ATTR_ROW::Resize to trim down when narrower, or extend
        // the last attr when wider.
        auto& newRow = newBuffer.GetRowByOffset(newRowY);
        const auto newWidth = newBuffer.GetLineWidth(newRowY);
        newRow.GetAttrRow() = row.GetAttrRow();
        newRow.GetAttrRow().Resize(newWidth);

        newRowY++;
    }

    if (SUCCEEDED(hr))