From 74ea4b47f0a11bce40e84d3ec29bee2930bfd6e3 Mon Sep 17 00:00:00 2001 From: Ron Dahlgren Date: Mon, 17 Nov 2025 17:35:35 -0500 Subject: [PATCH 01/10] Mask API key when a client is displayed as a string This commit implements `to_s` and `inspect` to mask everything after the first four characters of the api key. When using the Ruby SerpAPI client in pry, for instance, the default `inspect` representation will include the `api_key` of the `@params` attribute. --- lib/serpapi/client.rb | 14 ++++++++++++++ spec/serpapi/client/client_spec.rb | 21 ++++++++++++++++++++- 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/lib/serpapi/client.rb b/lib/serpapi/client.rb index ff1e583..a83f5f7 100644 --- a/lib/serpapi/client.rb +++ b/lib/serpapi/client.rb @@ -181,6 +181,20 @@ def close @socket.close if @socket end + def to_s + # If the api_key is set, mask it + masked_api_key = if api_key && api_key.length > 4 + "#{api_key[0..3]}#{'*' * (api_key.length - 4)}" + else + api_key + end + "SerpApi::Client(engine: #{engine}, api_key: #{masked_api_key}, persistent: #{persistent?}, timeout: #{timeout}s)" + end + + def inspect + to_s + end + private # @param [Hash] params to merge with default parameters provided to the constructor. diff --git a/spec/serpapi/client/client_spec.rb b/spec/serpapi/client/client_spec.rb index a5f395c..fc5b379 100644 --- a/spec/serpapi/client/client_spec.rb +++ b/spec/serpapi/client/client_spec.rb @@ -95,6 +95,25 @@ raise("wrong exception: #{e}") end end + + it 'should not expose api_key in to_s and inspect' do + str = client.to_s + expect(str).to include('SerpApi::Client(engine: google, api_key: ') + expect(str).to_not include(ENV['SERPAPI_KEY']) + + inspect_str = client.inspect + expect(inspect_str).to include('SerpApi::Client(engine: google, api_key: ') + expect(inspect_str).to_not include(ENV['SERPAPI_KEY']) + end + + it 'should gracefully handle api_key values shorter than 5 characters' do + short_key_client = SerpApi::Client.new(engine: 'google', api_key: 'abcd', timeout: 10) + str = short_key_client.to_s + expect(str).to include('SerpApi::Client(engine: google, api_key: abcd') + + inspect_str = short_key_client.inspect + expect(inspect_str).to include('SerpApi::Client(engine: google, api_key: abcd') + end end describe 'SerpApi client with persitency enable' do @@ -136,4 +155,4 @@ expect(client.socket).to be_nil expect(client.close).to be_nil end -end \ No newline at end of file +end From 17f344e482458d4cd2e72aa8819b6b24fdefc979 Mon Sep 17 00:00:00 2001 From: Ron Dahlgren Date: Mon, 17 Nov 2025 17:51:56 -0500 Subject: [PATCH 02/10] Bump version 1.0.1 to 1.0.2 --- README.md | 3 ++- README.md.erb | 3 ++- lib/serpapi/version.rb | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 7936864..05d3c5a 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ Other versions, such as Ruby 1.9, Ruby 2.x, and JRuby, are compatible with [lega ### Bundler ```ruby -gem 'serpapi', '~> 1.0', '>= 1.0.1' +gem 'serpapi', '~> 1.0', '>= 1.0.2' ``` ### Gem @@ -1085,6 +1085,7 @@ Ruby versions validated by Github Actions: * doc: [Github Actions.](https://github.com/serpapi/serpapi-ruby/actions/workflows/ci.yml) ## Change logs + * [2025-11-17] 1.0.2 Implement `to_s` and `inspect` functions for client * [2025-07-18] 1.0.1 Add support for old Ruby versions (2.7, 3.0) * [2025-07-01] 1.0.0 Full API support diff --git a/README.md.erb b/README.md.erb index 13b0ba5..11393bd 100644 --- a/README.md.erb +++ b/README.md.erb @@ -42,7 +42,7 @@ Other versions, such as Ruby 1.9, Ruby 2.x, and JRuby, are compatible with [lega ### Bundler ```ruby -gem 'serpapi', '~> 1.0', '>= 1.0.1' +gem 'serpapi', '~> 1.0', '>= 1.0.2' ``` ### Gem @@ -566,6 +566,7 @@ Ruby versions validated by Github Actions: * doc: [Github Actions.](https://github.com/serpapi/serpapi-ruby/actions/workflows/ci.yml) ## Change logs + * [2025-11-17] 1.0.2 Implement `to_s` and `inspect` functions for client * [2025-07-18] 1.0.1 Add support for old Ruby versions (2.7, 3.0) * [2025-07-01] 1.0.0 Full API support diff --git a/lib/serpapi/version.rb b/lib/serpapi/version.rb index 6f56435..954b930 100644 --- a/lib/serpapi/version.rb +++ b/lib/serpapi/version.rb @@ -1,4 +1,4 @@ module SerpApi # Current version of the gem - VERSION = '1.0.1'.freeze + VERSION = '1.0.2'.freeze end From e7da9cf78bf14fe607ac300dd981109eb7605c3c Mon Sep 17 00:00:00 2001 From: Ron Dahlgren Date: Tue, 18 Nov 2025 11:02:05 -0500 Subject: [PATCH 03/10] Follow `inspect` format conventions, do not override `to_s` --- lib/serpapi/client.rb | 13 ++----------- spec/serpapi/client/client_spec.rb | 15 +++++---------- 2 files changed, 7 insertions(+), 21 deletions(-) diff --git a/lib/serpapi/client.rb b/lib/serpapi/client.rb index a83f5f7..684e108 100644 --- a/lib/serpapi/client.rb +++ b/lib/serpapi/client.rb @@ -181,18 +181,9 @@ def close @socket.close if @socket end - def to_s - # If the api_key is set, mask it - masked_api_key = if api_key && api_key.length > 4 - "#{api_key[0..3]}#{'*' * (api_key.length - 4)}" - else - api_key - end - "SerpApi::Client(engine: #{engine}, api_key: #{masked_api_key}, persistent: #{persistent?}, timeout: #{timeout}s)" - end - def inspect - to_s + masked_key = api_key && (api_key.length > 4 ? "#{api_key[..1]}****#{api_key[-2..]}" : '****') + "#<#{self.class} @engine=#{engine} @timeout=#{timeout} @persistent=#{persistent} api_key=#{masked_key}>" end private diff --git a/spec/serpapi/client/client_spec.rb b/spec/serpapi/client/client_spec.rb index fc5b379..52518b3 100644 --- a/spec/serpapi/client/client_spec.rb +++ b/spec/serpapi/client/client_spec.rb @@ -96,23 +96,18 @@ end end - it 'should not expose api_key in to_s and inspect' do - str = client.to_s - expect(str).to include('SerpApi::Client(engine: google, api_key: ') - expect(str).to_not include(ENV['SERPAPI_KEY']) - + it 'should not expose api_key via inspect' do inspect_str = client.inspect - expect(inspect_str).to include('SerpApi::Client(engine: google, api_key: ') + expect(inspect_str).to include('# Date: Mon, 24 Nov 2025 15:44:01 -0500 Subject: [PATCH 04/10] include `object_id` in `inspect` result Co-authored-by: Andy --- lib/serpapi/client.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/serpapi/client.rb b/lib/serpapi/client.rb index 684e108..78e2867 100644 --- a/lib/serpapi/client.rb +++ b/lib/serpapi/client.rb @@ -183,7 +183,7 @@ def close def inspect masked_key = api_key && (api_key.length > 4 ? "#{api_key[..1]}****#{api_key[-2..]}" : '****') - "#<#{self.class} @engine=#{engine} @timeout=#{timeout} @persistent=#{persistent} api_key=#{masked_key}>" + "#<#{self.class}:#{'%#016x' % (object_id << 1)} @engine=#{engine} @timeout=#{timeout} @persistent=#{persistent} api_key=#{masked_key}>" end private From 9813628bd4d66185d1dc45c958db1faf87ce97fd Mon Sep 17 00:00:00 2001 From: "Ron @ SWGY" <125934174+ron-at-swgy@users.noreply.github.com> Date: Mon, 24 Nov 2025 15:44:58 -0500 Subject: [PATCH 05/10] Lengthen masked key representation Co-authored-by: Andy --- lib/serpapi/client.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/serpapi/client.rb b/lib/serpapi/client.rb index 78e2867..4ec6851 100644 --- a/lib/serpapi/client.rb +++ b/lib/serpapi/client.rb @@ -182,7 +182,7 @@ def close end def inspect - masked_key = api_key && (api_key.length > 4 ? "#{api_key[..1]}****#{api_key[-2..]}" : '****') + masked_key = api_key && (api_key.length > 8 ? "#{api_key[..3]}****#{api_key[-4..]}" : '****') "#<#{self.class}:#{'%#016x' % (object_id << 1)} @engine=#{engine} @timeout=#{timeout} @persistent=#{persistent} api_key=#{masked_key}>" end From ca9fdcb631a1d231baad1bab109799ce358b4f6e Mon Sep 17 00:00:00 2001 From: Ron Dahlgren Date: Mon, 24 Nov 2025 19:38:22 -0500 Subject: [PATCH 06/10] Broaden test to check for exclusion of the API key --- spec/serpapi/client/client_spec.rb | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/spec/serpapi/client/client_spec.rb b/spec/serpapi/client/client_spec.rb index 52518b3..9bd89b0 100644 --- a/spec/serpapi/client/client_spec.rb +++ b/spec/serpapi/client/client_spec.rb @@ -98,15 +98,13 @@ it 'should not expose api_key via inspect' do inspect_str = client.inspect - expect(inspect_str).to include('# Date: Mon, 24 Nov 2025 20:05:19 -0500 Subject: [PATCH 07/10] Lint: prefer format over '%' --- lib/serpapi/client.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/serpapi/client.rb b/lib/serpapi/client.rb index 4ec6851..13f3727 100644 --- a/lib/serpapi/client.rb +++ b/lib/serpapi/client.rb @@ -183,7 +183,7 @@ def close def inspect masked_key = api_key && (api_key.length > 8 ? "#{api_key[..3]}****#{api_key[-4..]}" : '****') - "#<#{self.class}:#{'%#016x' % (object_id << 1)} @engine=#{engine} @timeout=#{timeout} @persistent=#{persistent} api_key=#{masked_key}>" + "#<#{self.class}:#{format('%#016x', object_id << 1)} @engine=#{engine} @timeout=#{timeout} @persistent=#{persistent} api_key=#{masked_key}>" end private From 0cae5d8eb76d320cc0b38c8a831419a59f0dce47 Mon Sep 17 00:00:00 2001 From: Ron Dahlgren Date: Thu, 27 Nov 2025 10:43:28 -0500 Subject: [PATCH 08/10] Revert "include `object_id` in `inspect` result" This reverts commit d83a39411b6c24c5040ebedd36b7ecd32a61a6c0. --- lib/serpapi/client.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/serpapi/client.rb b/lib/serpapi/client.rb index 13f3727..ec5fe76 100644 --- a/lib/serpapi/client.rb +++ b/lib/serpapi/client.rb @@ -183,7 +183,7 @@ def close def inspect masked_key = api_key && (api_key.length > 8 ? "#{api_key[..3]}****#{api_key[-4..]}" : '****') - "#<#{self.class}:#{format('%#016x', object_id << 1)} @engine=#{engine} @timeout=#{timeout} @persistent=#{persistent} api_key=#{masked_key}>" + "#<#{self.class} @engine=#{engine} @timeout=#{timeout} @persistent=#{persistent} api_key=#{masked_key}>" end private From 471219a246b03a6d6bd37c116cf6b1f9b4ca0370 Mon Sep 17 00:00:00 2001 From: Ron Dahlgren Date: Fri, 28 Nov 2025 15:00:00 -0500 Subject: [PATCH 09/10] Remove newline --- spec/serpapi/client/client_spec.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/spec/serpapi/client/client_spec.rb b/spec/serpapi/client/client_spec.rb index 9bd89b0..52f1c5c 100644 --- a/spec/serpapi/client/client_spec.rb +++ b/spec/serpapi/client/client_spec.rb @@ -105,7 +105,6 @@ short_key_client = SerpApi::Client.new(engine: 'google', api_key: 'abcdef', timeout: 10) inspect_str = short_key_client.inspect expect(inspect_str).to_not include('abcdef') - end end From eee8082feb6819947d97452e7434a3166fd397f0 Mon Sep 17 00:00:00 2001 From: Ron Dahlgren Date: Fri, 28 Nov 2025 15:00:14 -0500 Subject: [PATCH 10/10] Correct release note summary for v1.0.2 --- README.md | 2 +- README.md.erb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 05d3c5a..b1d0247 100644 --- a/README.md +++ b/README.md @@ -1085,7 +1085,7 @@ Ruby versions validated by Github Actions: * doc: [Github Actions.](https://github.com/serpapi/serpapi-ruby/actions/workflows/ci.yml) ## Change logs - * [2025-11-17] 1.0.2 Implement `to_s` and `inspect` functions for client + * [2025-11-17] 1.0.2 Implement `inspect` functions for client * [2025-07-18] 1.0.1 Add support for old Ruby versions (2.7, 3.0) * [2025-07-01] 1.0.0 Full API support diff --git a/README.md.erb b/README.md.erb index 11393bd..625e08d 100644 --- a/README.md.erb +++ b/README.md.erb @@ -566,7 +566,7 @@ Ruby versions validated by Github Actions: * doc: [Github Actions.](https://github.com/serpapi/serpapi-ruby/actions/workflows/ci.yml) ## Change logs - * [2025-11-17] 1.0.2 Implement `to_s` and `inspect` functions for client + * [2025-11-17] 1.0.2 Implement `inspect` functions for client * [2025-07-18] 1.0.1 Add support for old Ruby versions (2.7, 3.0) * [2025-07-01] 1.0.0 Full API support