each_pair

in lib/gitlab/background_migration/normalize_ldap_extern_uids_range.rb [52:189]


              def each_pair
                state = :key
                key = StringIO.new
                value = StringIO.new
                hex_buffer = ""

                @dn.each_char.with_index do |char, dn_index|
                  case state
                  when :key then
                    case char
                    when 'a'..'z', 'A'..'Z' then
                      state = :key_normal
                      key << char
                    when '0'..'9' then
                      state = :key_oid
                      key << char
                    when ' ' then state = :key
                    else raise(MalformedError, "Unrecognized first character of an RDN attribute type name \"#{char}\"")
                    end
                  when :key_normal then
                    case char
                    when '=' then state = :value
                    when 'a'..'z', 'A'..'Z', '0'..'9', '-', ' ' then key << char
                    else raise(MalformedError, "Unrecognized RDN attribute type name character \"#{char}\"")
                    end
                  when :key_oid then
                    case char
                    when '=' then state = :value
                    when '0'..'9', '.', ' ' then key << char
                    else raise(MalformedError, "Unrecognized RDN OID attribute type name character \"#{char}\"")
                    end
                  when :value then
                    case char
                    when '\\' then state = :value_normal_escape
                    when '"' then state = :value_quoted
                    when ' ' then state = :value
                    when '#' then
                      state = :value_hexstring
                      value << char
                    when ',' then
                      state = :key
                      yield key.string.strip, rstrip_except_escaped(value.string, dn_index)
                      key = StringIO.new
                      value = StringIO.new
                    else
                      state = :value_normal
                      value << char
                    end
                  when :value_normal then
                    case char
                    when '\\' then state = :value_normal_escape
                    when ',' then
                      state = :key
                      yield key.string.strip, rstrip_except_escaped(value.string, dn_index)
                      key = StringIO.new
                      value = StringIO.new
                    when '+' then raise(UnsupportedError, "Multivalued RDNs are not supported")
                    else value << char
                    end
                  when :value_normal_escape then
                    case char
                    when '0'..'9', 'a'..'f', 'A'..'F' then
                      state = :value_normal_escape_hex
                      hex_buffer = char
                    else
                      state = :value_normal
                      value << char
                    end
                  when :value_normal_escape_hex then
                    case char
                    when '0'..'9', 'a'..'f', 'A'..'F' then
                      state = :value_normal
                      value << "#{hex_buffer}#{char}".to_i(16).chr
                    else raise(MalformedError, "Invalid escaped hex code \"\\#{hex_buffer}#{char}\"")
                    end
                  when :value_quoted then
                    case char
                    when '\\' then state = :value_quoted_escape
                    when '"' then state = :value_end
                    else value << char
                    end
                  when :value_quoted_escape then
                    case char
                    when '0'..'9', 'a'..'f', 'A'..'F' then
                      state = :value_quoted_escape_hex
                      hex_buffer = char
                    else
                      state = :value_quoted
                      value << char
                    end
                  when :value_quoted_escape_hex then
                    case char
                    when '0'..'9', 'a'..'f', 'A'..'F' then
                      state = :value_quoted
                      value << "#{hex_buffer}#{char}".to_i(16).chr
                    else raise(MalformedError, "Expected the second character of a hex pair inside a double quoted value, but got \"#{char}\"")
                    end
                  when :value_hexstring then
                    case char
                    when '0'..'9', 'a'..'f', 'A'..'F' then
                      state = :value_hexstring_hex
                      value << char
                    when ' ' then state = :value_end
                    when ',' then
                      state = :key
                      yield key.string.strip, rstrip_except_escaped(value.string, dn_index)
                      key = StringIO.new
                      value = StringIO.new
                    else raise(MalformedError, "Expected the first character of a hex pair, but got \"#{char}\"")
                    end
                  when :value_hexstring_hex then
                    case char
                    when '0'..'9', 'a'..'f', 'A'..'F' then
                      state = :value_hexstring
                      value << char
                    else raise(MalformedError, "Expected the second character of a hex pair, but got \"#{char}\"")
                    end
                  when :value_end then
                    case char
                    when ' ' then state = :value_end
                    when ',' then
                      state = :key
                      yield key.string.strip, rstrip_except_escaped(value.string, dn_index)
                      key = StringIO.new
                      value = StringIO.new
                    else raise(MalformedError, "Expected the end of an attribute value, but got \"#{char}\"")
                    end
                  else raise "Fell out of state machine"
                  end
                end

                
                raise(MalformedError, 'DN string ended unexpectedly') unless
                  [:value, :value_normal, :value_hexstring, :value_end].include? state

                yield key.string.strip, rstrip_except_escaped(value.string, @dn.length)
              end