Skip to content

Commit

Permalink
Fix parser of ASN.1 tag by saving property into type
Browse files Browse the repository at this point in the history
  • Loading branch information
fenrir-naru committed Apr 2, 2024
1 parent 4f8ae11 commit 4b80022
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 55 deletions.
31 changes: 20 additions & 11 deletions lib/gps_pvt/asn1/asn1.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
require 'set'

module GPS_PVT
end

Expand Down Expand Up @@ -282,6 +284,23 @@ module GPS_PVT
:UTCTime => 23, # @see 43.3
}[type[0]]
}

reorder_children = proc{|type_opts|
# reordering when automatic tagging transformation is not selected
tags = Set[]
[type_opts[:root], type_opts[:extension]].compact.each{|items|
items.collect!{|v|
tag = v[:type][1][:tag]
tag_class_num = case tag
when Array; [{"APPLICATION" => 1, "PRIVATE" => 3}[tag[0]], tag[1]]
when Integer; [2, tag] # (Context-specific)
else; [0, get_universal_class_number.call(v[:type])] # UNIVERSAL
end
raise unless tags.add?(tag_class_num) # Identical tag is already existed!
[v, tag_class_num]
}.sort!{|a, b| a[1] <=> b[1]}.collect!{|v| v[0]}
}
}

prepare_coding = proc{|tree|
next tree.each{|k, v|
Expand Down Expand Up @@ -330,17 +349,7 @@ module GPS_PVT
opts[:size_range] = find_range.call(opts, :size)
prepare_coding.call(opts)
when :CHOICE
[opts[:root], opts[:extension]].compact.each{|items|
# reordering when automatic tagging transformation is not selected
items.collect!{|v|
tag_class, tag_num = case v[:tag]
when Array; [{"APPLICATION" => 1, "PRIVATE" => 3}[v[:tag][0]], v[:tag][1]]
when Integer; [2, v[:tag]] # (Context-specific)
else; [0, get_universal_class_number.call(v[:type])] # UNIVERSAL
end
[v, [tag_class, tag_num]]
}.sort!{|a, b| a[1] <=> b[1]}.collect!{|v| v[0]}
} if (opts[:automatic_tagging] == false)
reorder_children.call(opts) if (opts[:automatic_tagging] == false)
opts[:extension] = opts[:extension].collect{|v|
v[:group] || [v] # 22. Note says "Version brackets have no effect"
}.flatten(1) if opts[:extension]
Expand Down
10 changes: 7 additions & 3 deletions lib/gps_pvt/asn1/asn1.y
Original file line number Diff line number Diff line change
Expand Up @@ -441,7 +441,9 @@ rule
# 28.2
val[2].merge!({:automatic_tagging => false}) \
if (@tags != :AUTOMATIC) \
|| (val[2][:root] + (val[2][:extension] || [])).any?{|v| v[:tag]}
|| (val[2][:root] + (val[2][:extension] || [])).any?{|v|
v[:type][1][:tag] rescue false
}
result = {:type => [val[0], val[2]]}
}
/*
Expand Down Expand Up @@ -488,9 +490,11 @@ rule
| Tag EXPLICIT Type*/
TaggedType :
Tag TaggingConstruction Type {
result = {:tag => val[0]}.merge(val[2])
result = val[2] # => {} having :type or :typeref keys
result[:type] = [result[:type]].flatten(1)
(result[:type][1] ||= {}).merge!({:tag => val[0]})
# TODO 30.6 c) to check whether Type is an untagged CHOICE after extraction of ReferencedType
result.merge!({:tag_cnstr => val[1]}) if val[1]
result[:type][1].merge!({:tag_cnstr => val[1]}) if val[1]
}
TaggingConstruction :
IMPLICIT {result = nil}
Expand Down
Binary file modified lib/gps_pvt/upl/upl.json.gz
Binary file not shown.
73 changes: 32 additions & 41 deletions spec/gps_pvt/asn1/per_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -72,97 +72,91 @@
[<<-'__JSON__',
{"X691_A1": {
"PersonnelRecord": {
"tag": ["APPLICATION", 0],
"type": [
"SEQUENCE",
{"root": [
{"name": "name", "typeref": "Name"},
{"name": "number", "typeref": "EmployeeNumber"},
{"name": "title", "tag": 0, "type": "VisibleString"},
{"name": "dateOfHire", "tag": 1, "typeref": "Date"},
{"name": "nameOfSpouse", "tag": 2, "typeref": "Name"},
{"name": "title", "type": ["VisibleString", {"tag": 0}]},
{"name": "dateOfHire", "typeref": "Date", "type": [null, {"tag": 1}]},
{"name": "nameOfSpouse", "typeref": "Name", "type": [null, {"tag": 2}]},
{"name": "children",
"tag": 3,
"type": [
"SEQUENCE_OF",
{"typeref": "ChildInformation"}
{"typeref": "ChildInformation", "tag": 3}
],
"default": []
}
] }
], "tag": ["APPLICATION", 0]}
]
},
"ChildInformation": {
"type": [
"SEQUENCE",
{"root": [
{"name": "name", "typeref": "Name"},
{"name": "dateOfBirth", "tag": 0, "typeref": "Date"}
{"name": "dateOfBirth", "typeref": "Date", "type": [null, {"tag": 0}]}
] }
]
},
"Name": {
"tag": ["APPLICATION", 1],
"type": [
"SEQUENCE",
{"root": [
{"name": "givenName", "type": "VisibleString"},
{"name": "initial", "type": "VisibleString"},
{"name": "familyName", "type": "VisibleString"}
] }
], "tag": ["APPLICATION", 1]}
]
},
"EmployeeNumber": {"tag": ["APPLICATION", 2], "type": "INTEGER"},
"Date": {"tag": ["APPLICATION", 3], "type": "VisibleString"}
"EmployeeNumber": {"type": ["INTEGER", {"tag": ["APPLICATION", 2]}]},
"Date": {"type": ["VisibleString", {"tag": ["APPLICATION", 3]}]}
} }
__JSON__
<<-'__JSON__',
{"X691_A2": {
"PersonnelRecord": {
"tag": ["APPLICATION", 0],
"type": [
"SEQUENCE",
{"root": [
{"name": "name", "typeref": "Name"},
{"name": "number", "typeref": "EmployeeNumber"},
{"name": "title", "tag": 0, "type": "VisibleString"},
{"name": "dateOfHire", "tag": 1, "typeref": "Date"},
{"name": "nameOfSpouse", "tag": 2, "typeref": "Name"},
{"name": "title", "type": ["VisibleString", {"tag": 0}]},
{"name": "dateOfHire", "typeref": "Date", "type": [null, {"tag": 1}]},
{"name": "nameOfSpouse", "typeref": "Name", "type": [null, {"tag": 2}]},
{"name": "children",
"tag": 3,
"type": [
"SEQUENCE_OF",
{"typeref": "ChildInformation"}
{"typeref": "ChildInformation", "tag": 3}
],
"default": []
}
] }
], "tag": ["APPLICATION", 0]}
]
},
"ChildInformation": {
"type": [
"SEQUENCE",
{"root": [
{"name": "name", "typeref": "Name"},
{"name": "dateOfBirth", "tag": 0, "typeref": "Date"}
{"name": "dateOfBirth", "typeref": "Date", "type": [null, {"tag": 0}]}
] }
]
},
"Name": {
"tag": ["APPLICATION", 1],
"type": [
"SEQUENCE",
{"root": [
{"name": "givenName", "typeref": "NameString"},
{"name": "initial", "typeref": "NameString", "type": [null, {"size": 1}]},
{"name": "familyName", "typeref": "NameString"}
] }
], "tag": ["APPLICATION", 1]}
]
},
"EmployeeNumber": {"tag": ["APPLICATION", 2], "type": "INTEGER"},
"Date": {"tag": ["APPLICATION", 3], "type": [
"EmployeeNumber": {"type": ["INTEGER", {"tag": ["APPLICATION", 2]}]},
"Date": {"type": [
"VisibleString",
{"from": {"and": [[">=", "0"], ["<=", "9"]]}, "size": 8}
{"tag": ["APPLICATION", 3], "from": {"and": [[">=", "0"], ["<=", "9"]]}, "size": 8}
]},
"NameString": {"type": [
"VisibleString", {
Expand All @@ -175,62 +169,59 @@
<<-'__JSON__',
{"X691_A3": {
"PersonnelRecord": {
"tag": ["APPLICATION", 0],
"type": [
"SEQUENCE",
{"root": [
{"name": "name", "typeref": "Name"},
{"name": "number", "typeref": "EmployeeNumber"},
{"name": "title", "tag": 0, "type": "VisibleString"},
{"name": "dateOfHire", "tag": 1, "typeref": "Date"},
{"name": "nameOfSpouse", "tag": 2, "typeref": "Name"},
{"name": "title", "type": ["VisibleString", {"tag": 0}]},
{"name": "dateOfHire", "typeref": "Date", "type": [null, {"tag": 1}]},
{"name": "nameOfSpouse", "typeref": "Name", "type": [null, {"tag": 2}]},
{"name": "children",
"tag": 3,
"type": [
"SEQUENCE_OF",
{"typeref": "ChildInformation", "size": {"root": 2}}
{"typeref": "ChildInformation", "size": {"root": 2}, "tag": 3}
],
"optional": true
}
], "extension": [] }
], "extension": [], "tag": ["APPLICATION", 0]}
]
},
"ChildInformation": {
"type": [
"SEQUENCE",
{"root": [
{"name": "name", "typeref": "Name"},
{"name": "dateOfBirth", "tag": 0, "typeref": "Date"}
{"name": "dateOfBirth", "typeref": "Date", "type": [null, {"tag": 0}]}
], "extension": [
{"name": "sex", "tag": 1, "type": [
{"name": "sex", "type": [
"ENUMERATED",
{"root": {"male": 1, "female": 2, "unknown": 3}}],
{"root": {"male": 1, "female": 2, "unknown": 3}, "tag": 1}],
"optional": true
}
] }
]
},
"Name": {
"tag": ["APPLICATION", 1],
"type": [
"SEQUENCE",
{"root": [
{"name": "givenName", "typeref": "NameString"},
{"name": "initial", "typeref": "NameString", "type": [null, {"size": 1}]},
{"name": "familyName", "typeref": "NameString"}
], "extension": [] }
], "extension": [], "tag": ["APPLICATION", 1]}
]
},
"EmployeeNumber": {"tag": ["APPLICATION", 2], "type": [
"EmployeeNumber": {"type": [
"INTEGER",
{"value": {"root": {"and": [[">=", 0], ["<=", 9999]]}}}
{"value": {"root": {"and": [[">=", 0], ["<=", 9999]]}}, "tag": ["APPLICATION", 2]}
] },
"Date": {"tag": ["APPLICATION", 3], "type": [
"Date": {"type": [
"VisibleString",
{"from": {"and": [[">=", "0"], ["<=", "9"]]}, "size": {
"root": 8,
"additional": {"and": [[">=", 9], ["<=", 20]]}
}}
}, "tag": ["APPLICATION", 3]}
]},
"NameString": {"type": [
"VisibleString", {
Expand Down

0 comments on commit 4b80022

Please sign in to comment.