From 6141c6a181ed957f8d4291c8a1392328f741e8d5 Mon Sep 17 00:00:00 2001 From: Carlo Cabrera Date: Thu, 10 Jul 2025 03:58:39 +0800 Subject: [PATCH] formulary: prevent formulae from printing to stdout while being loaded Formulae can execute arbitrary Ruby code when being loaded. In particular, they can print to stdout with methods like `puts`. This can break the parsing of output of commands like `brew info --json=v2`. Let's fix that by capturing the output to stdout, and then printing those messages to stderr instead (using `opoo` to try to discourage formula authors from doing this). --- Library/Homebrew/formulary.rb | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/Library/Homebrew/formulary.rb b/Library/Homebrew/formulary.rb index 5a48b25d8b..ac24daddd1 100644 --- a/Library/Homebrew/formulary.rb +++ b/Library/Homebrew/formulary.rb @@ -97,6 +97,11 @@ module Formulary require "formula" require "ignorable" + require "stringio" + + # Capture stdout to prevent formulae from printing to stdout unexpectedly. + old_stdout = $stdout + $stdout = StringIO.new mod = Module.new remove_const(namespace) if const_defined?(namespace) @@ -133,6 +138,15 @@ module Formulary remove_const(namespace) raise new_exception, "", e.backtrace end + ensure + printed_to_stdout = $stdout.string.strip + if printed_to_stdout.present? + opoo <<~WARNING + Formula #{name} attempted to print the following while being loaded: + #{$stdout.string.strip} + WARNING + end + $stdout = old_stdout end sig { params(identifier: String).returns(String) }