Blame SOURCES/ovmf-ShellPkg-Shell-clean-up-bogus-member-types-in-SPLIT_.patch

eb7fe6
From 06ffc9beb27a82dea25bb4cd3825ea3b57df5df5 Mon Sep 17 00:00:00 2001
eb7fe6
From: Laszlo Ersek <lersek@redhat.com>
eb7fe6
Date: Wed, 26 Apr 2017 14:20:30 +0200
eb7fe6
Subject: [PATCH 1/2] ShellPkg/Shell: clean up bogus member types in SPLIT_LIST
eb7fe6
MIME-Version: 1.0
eb7fe6
Content-Type: text/plain; charset=UTF-8
eb7fe6
Content-Transfer-Encoding: 8bit
eb7fe6
eb7fe6
Message-id: <20170426122031.12047-2-lersek@redhat.com>
eb7fe6
Patchwork-id: 74883
eb7fe6
O-Subject:  [RHEL-7.4 ovmf PATCH 1/2] ShellPkg/Shell: clean up bogus member types
eb7fe6
	in SPLIT_LIST
eb7fe6
Bugzilla: 1442908
eb7fe6
Acked-by: Thomas Huth <thuth@redhat.com>
eb7fe6
Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
eb7fe6
Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
eb7fe6
eb7fe6
The "SPLIT_LIST.SplitStdOut" and "SPLIT_LIST.SplitStdIn" members currently
eb7fe6
have type (SHELL_FILE_HANDLE *). This is wrong; SHELL_FILE_HANDLE is
eb7fe6
already a pointer, there's no need to store a pointer to a pointer.
eb7fe6
eb7fe6
The error is obvious if we check where and how these members are used:
eb7fe6
eb7fe6
- In the RunSplitCommand() function, these members are used (populated)
eb7fe6
  extensively; this function has to be updated in sync.
eb7fe6
eb7fe6
  ConvertEfiFileProtocolToShellHandle() already returns the temporary
eb7fe6
  memory file created with CreateFileInterfaceMem() as SHELL_FILE_HANDLE,
eb7fe6
  not as (SHELL_FILE_HANDLE *).
eb7fe6
eb7fe6
- In particular, the ConvertShellHandleToEfiFileProtocol() calls need to
eb7fe6
  be dropped as well in RunSplitCommand(), since
eb7fe6
  EFI_SHELL_PROTOCOL.SetFilePosition() and EFI_SHELL_PROTOCOL.CloseFile()
eb7fe6
  take SHELL_FILE_HANDLE parameters, not (EFI_FILE_PROTOCOL *).
eb7fe6
eb7fe6
  Given that ConvertShellHandleToEfiFileProtocol() only performs a
eb7fe6
  type-cast (it does not adjust any pointer values), *and*
eb7fe6
  SHELL_FILE_HANDLE -- taken by EFI_SHELL_PROTOCOL member functions -- is
eb7fe6
  actually a typedef to (VOID *) -- see more on this later --, this
eb7fe6
  conversion error hasn't been caught by compilers.
eb7fe6
eb7fe6
- In the ProcessNewSplitCommandLine() function, RunSplitCommand() is
eb7fe6
  called either initially (passing in NULL / NULL; no update needed), or
eb7fe6
  recursively (passing in Split->SplitStdIn / Split->SplitStdOut; again no
eb7fe6
  update is necessary beyond the RunSplitCommand() modification above).
eb7fe6
eb7fe6
- In the UpdateStdInStdOutStdErr() and RestoreStdInStdOutStdErr()
eb7fe6
  functions, said structure members are compared and assigned to
eb7fe6
  "EFI_SHELL_PARAMETERS_PROTOCOL.StdIn" and
eb7fe6
  "EFI_SHELL_PARAMETERS_PROTOCOL.StdOut", both of which have type
eb7fe6
  SHELL_FILE_HANDLE, *not* (SHELL_FILE_HANDLE *).
eb7fe6
eb7fe6
  The compiler hasn't caught this error because of the fatally flawed type
eb7fe6
  definition of SHELL_FILE_HANDLE, namely
eb7fe6
eb7fe6
    typedef VOID *SHELL_FILE_HANDLE;
eb7fe6
eb7fe6
  Pointer-to-void silently converts to and from most other pointer types;
eb7fe6
  among them, pointer-to-pointer-to-void. That is also why no update is
eb7fe6
  necessary for UpdateStdInStdOutStdErr() and RestoreStdInStdOutStdErr()
eb7fe6
  in this fix.
eb7fe6
eb7fe6
(
eb7fe6
eb7fe6
Generally speaking, using (VOID *) typedefs for opaque handles is a tragic
eb7fe6
mistake in all of the UEFI-related specifications; this practice defeats
eb7fe6
any type checking that compilers might help programmers with. The right
eb7fe6
way to define an opaque handle is as follows:
eb7fe6
eb7fe6
  //
eb7fe6
  // Introduce the incomplete structure type, and the derived pointer
eb7fe6
  // type, in both the specification and the public edk2 headers. Note
eb7fe6
  // that the derived pointer type itself is a complete type, and it can
eb7fe6
  // be used freely by client code.
eb7fe6
  //
eb7fe6
  typedef struct SHELL_FILE *SHELL_FILE_HANDLE;
eb7fe6
eb7fe6
  //
eb7fe6
  // Complete the structure type in the edk2 internal C source files.
eb7fe6
  //
eb7fe6
  struct SHELL_FILE {
eb7fe6
    //
eb7fe6
    // list fields
eb7fe6
    //
eb7fe6
  };
eb7fe6
eb7fe6
This way the structure size and members remain hidden from client code,
eb7fe6
but the C compiler can nonetheless catch any invalid conversions between
eb7fe6
incompatible XXX_HANDLE types.
eb7fe6
eb7fe6
)
eb7fe6
eb7fe6
Cc: Jaben Carsey <jaben.carsey@intel.com>
eb7fe6
Cc: Marvin Häuser <Marvin.Haeuser@outlook.com>
eb7fe6
Cc: Qiu Shumin <shumin.qiu@intel.com>
eb7fe6
Cc: Ruiyu Ni <ruiyu.ni@intel.com>
eb7fe6
Contributed-under: TianoCore Contribution Agreement 1.0
eb7fe6
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
eb7fe6
Reviewed-by: Jaben Carsey <jaben.carsey@intel.com>
eb7fe6
(cherry picked from commit 1bd0bf153ebf4993421afd5084c52a6e57e17fdc)
eb7fe6
---
eb7fe6
 ShellPkg/Application/Shell/Shell.c | 12 ++++++------
eb7fe6
 ShellPkg/Application/Shell/Shell.h |  4 ++--
eb7fe6
 2 files changed, 8 insertions(+), 8 deletions(-)
eb7fe6
eb7fe6
diff --git a/ShellPkg/Application/Shell/Shell.c b/ShellPkg/Application/Shell/Shell.c
eb7fe6
index 731ba18..816dd1a 100644
eb7fe6
--- a/ShellPkg/Application/Shell/Shell.c
eb7fe6
+++ b/ShellPkg/Application/Shell/Shell.c
eb7fe6
@@ -1705,8 +1705,8 @@ ShellConvertVariables (
eb7fe6
 EFI_STATUS
eb7fe6
 RunSplitCommand(
eb7fe6
   IN CONST CHAR16             *CmdLine,
eb7fe6
-  IN       SHELL_FILE_HANDLE  *StdIn,
eb7fe6
-  IN       SHELL_FILE_HANDLE  *StdOut
eb7fe6
+  IN       SHELL_FILE_HANDLE  StdIn,
eb7fe6
+  IN       SHELL_FILE_HANDLE  StdOut
eb7fe6
   )
eb7fe6
 {
eb7fe6
   EFI_STATUS        Status;
eb7fe6
@@ -1715,7 +1715,7 @@ RunSplitCommand(
eb7fe6
   UINTN             Size1;
eb7fe6
   UINTN             Size2;
eb7fe6
   SPLIT_LIST        *Split;
eb7fe6
-  SHELL_FILE_HANDLE *TempFileHandle;
eb7fe6
+  SHELL_FILE_HANDLE TempFileHandle;
eb7fe6
   BOOLEAN           Unicode;
eb7fe6
 
eb7fe6
   ASSERT(StdOut == NULL);
eb7fe6
@@ -1781,7 +1781,7 @@ RunSplitCommand(
eb7fe6
     Split->SplitStdOut  = Split->SplitStdIn;
eb7fe6
   }
eb7fe6
   Split->SplitStdIn   = TempFileHandle;
eb7fe6
-  ShellInfoObject.NewEfiShellProtocol->SetFilePosition(ConvertShellHandleToEfiFileProtocol(Split->SplitStdIn), 0);
eb7fe6
+  ShellInfoObject.NewEfiShellProtocol->SetFilePosition (Split->SplitStdIn, 0);
eb7fe6
 
eb7fe6
   if (!EFI_ERROR(Status)) {
eb7fe6
     Status = RunCommand(NextCommandLine);
eb7fe6
@@ -1797,10 +1797,10 @@ RunSplitCommand(
eb7fe6
   // Note that the original StdIn is now the StdOut...
eb7fe6
   //
eb7fe6
   if (Split->SplitStdOut != NULL) {
eb7fe6
-    ShellInfoObject.NewEfiShellProtocol->CloseFile(ConvertShellHandleToEfiFileProtocol(Split->SplitStdOut));
eb7fe6
+    ShellInfoObject.NewEfiShellProtocol->CloseFile (Split->SplitStdOut);
eb7fe6
   }
eb7fe6
   if (Split->SplitStdIn != NULL) {
eb7fe6
-    ShellInfoObject.NewEfiShellProtocol->CloseFile(ConvertShellHandleToEfiFileProtocol(Split->SplitStdIn));
eb7fe6
+    ShellInfoObject.NewEfiShellProtocol->CloseFile (Split->SplitStdIn);
eb7fe6
     FreePool (Split->SplitStdIn);
eb7fe6
   }
eb7fe6
 
eb7fe6
diff --git a/ShellPkg/Application/Shell/Shell.h b/ShellPkg/Application/Shell/Shell.h
eb7fe6
index 25ac114..ff08494 100644
eb7fe6
--- a/ShellPkg/Application/Shell/Shell.h
eb7fe6
+++ b/ShellPkg/Application/Shell/Shell.h
eb7fe6
@@ -63,8 +63,8 @@ extern CONST CHAR16 mNoNestingFalse[];
eb7fe6
 
eb7fe6
 typedef struct {
eb7fe6
   LIST_ENTRY        Link;           ///< Standard linked list handler.
eb7fe6
-  SHELL_FILE_HANDLE *SplitStdOut;   ///< ConsoleOut for use in the split.
eb7fe6
-  SHELL_FILE_HANDLE *SplitStdIn;    ///< ConsoleIn for use in the split.
eb7fe6
+  SHELL_FILE_HANDLE SplitStdOut;    ///< ConsoleOut for use in the split.
eb7fe6
+  SHELL_FILE_HANDLE SplitStdIn;     ///< ConsoleIn for use in the split.
eb7fe6
 } SPLIT_LIST;
eb7fe6
 
eb7fe6
 typedef struct {
eb7fe6
-- 
eb7fe6
1.8.3.1
eb7fe6