rusticata / asn1-rs

Parsers/Encoders for ASN.1 BER/DER data
Apache License 2.0
9 stars 14 forks source link

`oid!` macro now fails if given anything besides a single expr #28

Closed lilyball closed 1 year ago

lilyball commented 1 year ago

The oid! macro in der-parser v6 accepted any number of tokens, which allowed me to construct an invocation to it in my own macro where I fed it a series of literals and periods. Trying this in v8 fails with a macro error, which appears to be due to the asn1-rs version of the macro expecting a single $items:expr arg instead of something like $($item:tt)+. This breaks my code as I construct a whole tree of oids using my own macro.

A simple reproduction looks like

// Code sample provided under the MIT license
macro_rules! foo {
  ($a:literal $b:literal $c:literal) => {
    der_parser::oid!($a.$b.$c)
  };
}

fn main() {
  dbg!(foo!(1 2 3));
}

This works just fine with der-parser v6 but fails with der-parser v8

error: unexpected token: `2`
 --> foo.rs:4:22
  |
4 |  der_parser::oid!($a.$b.$c)
  |                      ^^
...
9 |  dbg!(foo!(1 2 3));
  |       ----------- in this macro invocation
  |
  = note: this error originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)

error: no rules expected the token `2`
   --> foo.rs:4:22
    |
4   |  der_parser::oid!($a.$b.$c)
    |                      ^^ no rules expected this token in macro call
...
9   |  dbg!(foo!(1 2 3));
    |       ----------- in this macro invocation
    |
note: while trying to match meta-variable `$items:expr`
   --> /Users/lily/.cargo/registry/src/github.com-1ecc6299db9ec823/asn1-rs-0.5.2/src/asn1_types/oid.rs:462:6
    |
462 |     ($items:expr) => {
    |      ^^^^^^^^^^^
    = note: this error originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
chifflier commented 1 year ago

Thanks for the report The problem comes from the macro definition, which uses the expr type for the fragment specifiers. expr does not allow ., and so rejects the call (while calling the underlying proc-macro works perfectly). Since it cannot use only integers at this point, I will change it to literal