sup

A curses threads-with-tags style email client

sup.git

git clone https://supmua.dev/git/sup/
commit 8b19866b566b3e995e58d5b0e27575b6afa4ede7
parent 9385148ddddabaee7667a4fadc0580fd9ef1af02
Author: Matthieu Rakotojaona <matthieu.rakotojaona@gmail.com>
Date:   Wed, 29 Oct 2014 20:31:46 +0100

Wrap piping command inside a begin/rescue to catch invalid commands

Fixes #341

Diffstat:
M lib/sup/mode.rb | 55 ++++++++++++++++++++++++++++++-------------------------
M lib/sup/modes/text_mode.rb | 7 ++++++-
M lib/sup/modes/thread_view_mode.rb | 7 ++++++-
3 files changed, 42 insertions(+), 27 deletions(-)
diff --git a/lib/sup/mode.rb b/lib/sup/mode.rb
@@ -102,37 +102,42 @@ EOS
   end
 
   def pipe_to_process command
-    Open3.popen3(command) do |input, output, error|
-      err, data, * = IO.select [error], [input], nil
-
-      unless err.empty?
-        message = err.first.read
-        if message =~ /^\s*$/
-          warn "error running #{command} (but no error message)"
-          BufferManager.flash "Error running #{command}!"
-        else
-          warn "error running #{command}: #{message}"
-          BufferManager.flash "Error: #{message}"
+    begin
+      Open3.popen3(command) do |input, output, error|
+        err, data, * = IO.select [error], [input], nil
+
+        unless err.empty?
+          message = err.first.read
+          if message =~ /^\s*$/
+            warn "error running #{command} (but no error message)"
+            BufferManager.flash "Error running #{command}!"
+          else
+            warn "error running #{command}: #{message}"
+            BufferManager.flash "Error: #{message}"
+          end
+          return nil, false
         end
-        return
-      end
 
-      data = data.first
-      data.sync = false # buffer input
+        data = data.first
+        data.sync = false # buffer input
 
-      yield data
-      data.close # output will block unless input is closed
+        yield data
+        data.close # output will block unless input is closed
 
-      ## BUG?: shows errors or output but not both....
-      data, * = IO.select [output, error], nil, nil
-      data = data.first
+        ## BUG?: shows errors or output but not both....
+        data, * = IO.select [output, error], nil, nil
+        data = data.first
 
-      if data.eof
-        BufferManager.flash "'#{command}' done!"
-        nil
-      else
-        data.read
+        if data.eof
+          BufferManager.flash "'#{command}' done!"
+          return nil, true
+        else
+          return data.read, true
+        end
       end
+    rescue Errno::ENOENT
+      # If the command is invalid
+      return nil, false
     end
   end
 end
diff --git a/lib/sup/modes/text_mode.rb b/lib/sup/modes/text_mode.rb
@@ -24,10 +24,15 @@ class TextMode < ScrollMode
     command = BufferManager.ask(:shell, "pipe command: ")
     return if command.nil? || command.empty?
 
-    output = pipe_to_process(command) do |stream|
+    output, success = pipe_to_process(command) do |stream|
       @text.each { |l| stream.puts l }
     end
 
+    unless success
+      BufferManager.flash "Invalid command: '#{command}' is not an executable"
+      return
+    end
+
     if output
       BufferManager.spawn "Output of '#{command}'", TextMode.new(output.ascii)
     else
diff --git a/lib/sup/modes/thread_view_mode.rb b/lib/sup/modes/thread_view_mode.rb
@@ -722,7 +722,7 @@ EOS
     command = BufferManager.ask(:shell, "pipe command: ")
     return if command.nil? || command.empty?
 
-    output = pipe_to_process(command) do |stream|
+    output, success = pipe_to_process(command) do |stream|
       if chunk
         stream.print chunk.raw_content
       else
@@ -730,6 +730,11 @@ EOS
       end
     end
 
+    unless success
+      BufferManager.flash "Invalid command: '#{command}' is not an executable"
+      return
+    end
+
     if output
       BufferManager.spawn "Output of '#{command}'", TextMode.new(output.ascii)
     else