From 51e6db9a0edaebdac59a16c13b3bb4eddc823f14 Mon Sep 17 00:00:00 2001 From: Paul Thornthwaite Date: Wed, 17 Aug 2022 14:44:37 +0100 Subject: [PATCH] Fix `OpenStack.escape` with dash/extra characters There is a bug in the regexp used in `OpenStack.escape` in that when `extra_exclude_chars` is set, dash is no longer the last character in the pattern. This causes the regexp to treat it as a range, not a character of its own and that causes it to be escaped. # Before Fog::OpenStack.escape("test-pattern/", "/") # => "test%2Dpattern/" Fog::OpenStack.escape("test-pattern/") # => "test-pattern%2F" # After Fog::OpenStack.escape("test-pattern/", "/") # => "test-pattern/" It does not happen when `extra_exclude_chars` is blank. We spotted this in our Brightbox provider which was forked from the OpenStack implementation. It appears to have been fixed in Rackspace for a few years and copied into Google provider. --- lib/fog/openstack.rb | 2 +- spec/openstack_spec.rb | 27 +++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 spec/openstack_spec.rb diff --git a/lib/fog/openstack.rb b/lib/fog/openstack.rb index b1d308dae..aea8cdc43 100644 --- a/lib/fog/openstack.rb +++ b/lib/fog/openstack.rb @@ -93,7 +93,7 @@ def self.get_supported_microversion(supported_versions, uri, auth_token, connect # CGI.escape, but without special treatment on spaces def self.escape(str, extra_exclude_chars = '') - str.gsub(/([^a-zA-Z0-9_.-#{extra_exclude_chars}]+)/) do + str.gsub(/([^a-zA-Z0-9_.#{extra_exclude_chars}-]+)/) do '%' + $1.unpack('H2' * $1.bytesize).join('%').upcase end end diff --git a/spec/openstack_spec.rb b/spec/openstack_spec.rb new file mode 100644 index 000000000..8f8b6ee6f --- /dev/null +++ b/spec/openstack_spec.rb @@ -0,0 +1,27 @@ +require 'spec_helper' + +describe Fog::OpenStack do + describe ".escape" do + describe "when string includes dash" do + it "does not escape dashes" do + str = "this-is-hypenated" + assert_equal str, Fog::OpenStack.escape(str) + end + end + + describe "when string includes dash and extra characters" do + it "does not escape dashes" do + str = "this-is-hypenated/" + assert_equal str, Fog::OpenStack.escape(str, "/") + end + end + + describe "when string includes dash without extra characters" do + it "does not escape dashes" do + str = "this-is-hypenated/" + expected = "this-is-hypenated%2F" + assert_equal expected, Fog::OpenStack.escape(str) + end + end + end +end \ No newline at end of file