rasn1 0.15.0 → 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 44b823b6a8e75b419ef38d27be1a31464667f4a2729ce514702b83a34210e7cb
4
- data.tar.gz: 4e8f19d517834432999dac059bd175bc53330b224ffb554017efd6ebdca83e34
3
+ metadata.gz: f4b0dda0fa6e06b6371e74782ecc5b5cc5f9d30dab886a759aa5b9345bd80908
4
+ data.tar.gz: cfad20040d45598fffda3132bb9c417cdf4fca9dd78dda9616a4b7a0a6a98b97
5
5
  SHA512:
6
- metadata.gz: a44cdcea86cd6a7687cc0bb56475ee9325a5135acdd3b3408d5c1be936511279ed344d3811afa44a0eb658f01cd71a73fa49ea4c825e3d81d6c5746684e04076
7
- data.tar.gz: fadc12bb059a416ae8716857ef91a402969ef78d80ca767bfefe09237794e7accffc4a6876ab90400047efb63442b065508ef3ff5768d4df1f18f8d6890f0334
6
+ metadata.gz: a99c4ee238423b561470182c3ac415d9a9ff8f11d626af843d203d5c6aedff6969ec0e4b47f68844e4c62153dd238ba4d852f3855e63a091e8c2cf0643d39d89
7
+ data.tar.gz: 9614d3434f7b05fe01e80bb36cbd82914b565a6e5087e48bc5e44aa7f47d70076ac3b1f542062bf9bc203d8101f4afd21f2ad5b9865011cdff1359e8178c8b19
data/lib/rasn1/model.rb CHANGED
@@ -381,15 +381,24 @@ module RASN1
381
381
  lazy_initialize(args) unless args.empty?
382
382
  end
383
383
 
384
- # Access an element of the model by its name
385
- # @param [Symbol] name
386
- # @return [Model, Types::Base, Wrapper]
387
- def [](name)
388
- elt = @elements[name]
389
- return elt unless elt.is_a?(Proc)
390
-
391
- # Lazy element -> generate it
392
- @elements[name] = elt.call
384
+ # @overload [](name)
385
+ # Access an element of the model by its name
386
+ # @param [Symbol] name
387
+ # @return [Model, Types::Base, Wrapper]
388
+ # @overload [](idx)
389
+ # Access an element of root element by its index. Root element must be a {Sequence} or {SequenceOf}.
390
+ # @param [Integer] idx
391
+ # @return [Model, Types::Base, Wrapper]
392
+ def [](name_or_idx)
393
+ case name_or_idx
394
+ when Symbol
395
+ elt = @elements[name_or_idx]
396
+ return elt unless elt.is_a?(Proc)
397
+
398
+ @elements[name_or_idx] = elt.call
399
+ when Integer
400
+ root[name_or_idx]
401
+ end
393
402
  end
394
403
 
395
404
  # Set value of element +name+. Element should be a {Types::Base}.
@@ -582,13 +591,13 @@ module RASN1
582
591
  private
583
592
 
584
593
  def generate_root(args)
585
- opts = args.slice(:explicit, :implicit, :optional, :class, :default, :constructed, :tag_value)
594
+ opts = args.slice(:name, :explicit, :implicit, :optional, :class, :default, :constructed, :tag_value)
586
595
  root = self.class.class_eval { @root }
587
596
  root_options = self.class.options || {}
588
597
  root_options.merge!(opts)
598
+ @root_name = args[:name] || root.name
589
599
  @root = generate_element(root, root_options)
590
- @root_name = root.name
591
- @elements[root.name] = @root
600
+ @elements[@root_name] = @root
592
601
  end
593
602
 
594
603
  def generate_element(elt, opts={})
@@ -596,15 +605,23 @@ module RASN1
596
605
  when BaseElem
597
606
  generate_base_element(elt, opts)
598
607
  when ModelElem
608
+ opts[:name] ||= elt.name
599
609
  elt.klass.new(opts)
600
610
  when WrapElem
601
- wrapped = elt.element.is_a?(ModelElem) ? elt.element.klass : generate_element(elt.element)
602
- wrapper = Wrapper.new(wrapped, elt.options.merge(opts))
603
- @elements[elt.element.name] = proc { wrapper.element }
604
- wrapper
611
+ generate_wrapper_element(elt, opts)
605
612
  end
606
613
  end
607
614
 
615
+ def generate_wrapper_element(elt, opts)
616
+ wrapped = elt.element.is_a?(ModelElem) ? elt.element.klass : generate_element(elt.element)
617
+ options = elt.options.merge(opts)
618
+ options[:name] = elt.element.name if elt.element.is_a?(ModelElem)
619
+ wrapper = Wrapper.new(wrapped, options)
620
+ # Use a proc as wrapper may be lazy
621
+ @elements[elt.element.name] = proc { wrapper.element }
622
+ wrapper
623
+ end
624
+
608
625
  def generate_base_element(elt, opts)
609
626
  element = elt.proc.call(opts)
610
627
  return element if elt.content.nil?
@@ -616,19 +633,20 @@ module RASN1
616
633
  element
617
634
  end
618
635
 
636
+ # @author sdaubert
637
+ # @author lemontree55
638
+ # @author adfoster-r7
619
639
  def private_to_h(element=nil) # rubocop:disable Metrics/CyclomaticComplexity
620
640
  my_element = element || root
621
- my_element = my_element.root if my_element.is_a?(Model)
622
641
  value = case my_element
642
+ when Model
643
+ model_to_h(my_element)
623
644
  when Types::SequenceOf
624
645
  sequence_of_to_h(my_element)
625
646
  when Types::Sequence
626
647
  sequence_to_h(my_element)
627
- # @author adfoster-r7
628
648
  when Types::Choice
629
- raise ChoiceError.new(my_element) if my_element.chosen.nil?
630
-
631
- private_to_h(my_element.value[my_element.chosen])
649
+ choice_to_h(my_element)
632
650
  when Wrapper
633
651
  wrapper_to_h(my_element)
634
652
  else
@@ -641,6 +659,15 @@ module RASN1
641
659
  end
642
660
  end
643
661
 
662
+ def model_to_h(elt)
663
+ hsh = elt.to_h
664
+ if root.is_a?(Types::Choice)
665
+ hsh[hsh.keys.first]
666
+ else
667
+ { @elements.key(elt) => hsh[hsh.keys.first] }
668
+ end
669
+ end
670
+
644
671
  def sequence_of_to_h(elt)
645
672
  if elt.of_type < Model
646
673
  elt.value&.map { |el| el.to_h.values.first }
@@ -655,8 +682,7 @@ module RASN1
655
682
 
656
683
  case el
657
684
  when Model
658
- hsh = el.to_h
659
- [@elements.key(el), hsh[hsh.keys.first]]
685
+ model_to_h(el).to_a[0]
660
686
  when Wrapper
661
687
  [unwrap_keyname(@elements.key(el)), wrapper_to_h(el)]
662
688
  else
@@ -666,6 +692,13 @@ module RASN1
666
692
  ary.compact.to_h
667
693
  end
668
694
 
695
+ def choice_to_h(elt)
696
+ raise ChoiceError.new(elt) if elt.chosen.nil?
697
+
698
+ chosen = elt.value[elt.chosen]
699
+ { chosen.name => private_to_h(chosen) }
700
+ end
701
+
669
702
  def unwrap_keyname(key)
670
703
  key.to_s.delete_suffix('_wrapper').to_sym
671
704
  end
@@ -359,7 +359,7 @@ module RASN1
359
359
  lines << str
360
360
  end
361
361
  str[compute_trace_index(byte_count, 3), 2] = '%02x' % byte
362
- str[compute_trace_index(byte_count, 1, 49)] = byte >= 32 && byte <= 126 ? byte.chr : '.'
362
+ str[compute_trace_index(byte_count, 1, 49)] = byte.between?(32, 126) ? byte.chr : '.'
363
363
  byte_count += 1
364
364
  end
365
365
  lines.map(&:rstrip).join << "\n"
@@ -546,7 +546,11 @@ module RASN1
546
546
  end
547
547
  end
548
548
 
549
- def check_id(der)
549
+ # Check ID from +der+ is the one expected
550
+ # @return [Boolean] +true+ is ID is expected, +false+ if it is not but +self+ is {#optional?}
551
+ # or has a {#default} value.
552
+ # @raise [ASN1Error] ID was not expected, is not optional and has no default value
553
+ def check_id(der) # rubocop:disable Naming/PredicateMethod
550
554
  expected_id = encode_identifier_octets
551
555
  real_id = der[0, expected_id.size]
552
556
  return true if real_id == expected_id
@@ -14,7 +14,7 @@ module RASN1
14
14
  DER_FALSE = 0
15
15
 
16
16
  # @return [false]
17
- def void_value
17
+ def void_value # rubocop:disable Naming/PredicateMethod
18
18
  false
19
19
  end
20
20
 
@@ -4,7 +4,7 @@ module RASN1
4
4
  module Types
5
5
  # Create VisibleString as a Constrained subclass of IA5String
6
6
  Types.define_type(:VisibleString, from: IA5String) do |value|
7
- value.nil? || value.chars.all? { |c| c.ord >= 32 && c.ord <= 126 }
7
+ value.nil? || value.chars.all? { |c| c.ord.between?(32, 126) }
8
8
  end
9
9
 
10
10
  # ASN.1 Visible String
data/lib/rasn1/version.rb CHANGED
@@ -2,5 +2,5 @@
2
2
 
3
3
  module RASN1
4
4
  # RASN1 version number
5
- VERSION = '0.15.0'
5
+ VERSION = '0.16.0'
6
6
  end
data/lib/rasn1.rb CHANGED
@@ -26,7 +26,7 @@ module RASN1
26
26
  # @param [String] der binary string to parse
27
27
  # @param [Boolean] ber if +true+, decode a BER string, else a DER one
28
28
  # @return [Types::Base]
29
- def self.parse(der, ber: false) # rubocop:disable Metrics:AbcSize
29
+ def self.parse(der, ber: false) # rubocop:disable Metrics/AbcSize
30
30
  type = Types.id2type(der)
31
31
  type.parse!(der, ber: ber)
32
32
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rasn1
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.15.0
4
+ version: 0.16.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - LemonTree55
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-01-03 00:00:00.000000000 Z
11
+ date: 2025-06-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: strptime