Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'lib/gitlab/ci/interpolation/access.rb')
-rw-r--r--lib/gitlab/ci/interpolation/access.rb56
1 files changed, 56 insertions, 0 deletions
diff --git a/lib/gitlab/ci/interpolation/access.rb b/lib/gitlab/ci/interpolation/access.rb
new file mode 100644
index 00000000000..42598458902
--- /dev/null
+++ b/lib/gitlab/ci/interpolation/access.rb
@@ -0,0 +1,56 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Ci
+ module Interpolation
+ class Access
+ attr_reader :content, :errors
+
+ MAX_ACCESS_OBJECTS = 5
+ MAX_ACCESS_BYTESIZE = 1024
+
+ def initialize(access, ctx)
+ @content = access
+ @ctx = ctx
+ @errors = []
+
+ if objects.count <= 1 # rubocop:disable Style/IfUnlessModifier
+ @errors.push('invalid interpolation access pattern')
+ end
+
+ if access.bytesize > MAX_ACCESS_BYTESIZE # rubocop:disable Style/IfUnlessModifier
+ @errors.push('maximum interpolation expression size exceeded')
+ end
+
+ evaluate! if valid?
+ end
+
+ def valid?
+ errors.none?
+ end
+
+ def objects
+ @objects ||= @content.split('.', MAX_ACCESS_OBJECTS)
+ end
+
+ def value
+ raise ArgumentError, 'access path invalid' unless valid?
+
+ @value
+ end
+
+ private
+
+ def evaluate!
+ raise ArgumentError, 'access path invalid' unless valid?
+
+ @value ||= objects.inject(@ctx) do |memo, value|
+ memo.fetch(value.to_sym)
+ end
+ rescue KeyError => e
+ @errors.push(e)
+ end
+ end
+ end
+ end
+end