Menu

#173 funny value assignments when no 'value' and doc is non-empty

autogen
closed
nobody
None
1
2020-09-14
2015-12-13
No

Hi,
Sometime ago I reported that autogen assigns random values to the short options in the --help view. The origin report is at: http://sourceforge.net/p/autogen/mailman/message/32189653/

A copy is below:
I've noticed in 5.18.2 that if I do not specify values in two options I
have different behavior depending on the value of "doc". That is if I
have:
flag = {
name = p12-info;
descrip = "Print information on a PKCS #12 structure";
doc = "";
};

The generated text in help is the expected:
' --to-p12 Generate a PKCS #12 structure'

However the following:

flag = {
name = rsa;
descrip = "Generate RSA key";
doc = "When combined with --generate-privkey generates an RSA
private key.";
};

results to:
' -", --rsa Generate RSA key'

Note the funny '-"' that was assigned. The funny assignments (using
values from "!@#$%^&*") seem to occur for all options that have no value
and set doc to something else than empty.

I'm opening this bug as a reminder and to allow tracking of the issue (since it is being reported by users https://gitlab.com/gnutls/gnutls/issues/57 )

Discussion

  • Bruce Korb

    Bruce Korb - 2016-02-20

    "Works for me." :( I am certain there is an issue, but I'm not seeing it.
    Could you please expand the following until you see the error? Thank you.

    ck-opts.def:

    autogen definitions options;
    prog_name       = "prog";
    prog_title      = "Fixup prog";
    argument    = "[ <file-name> ... ]";
    
    long-opts;
    gnu-usage;
    
    flag = {
        name = rsa;
        descrip = "Generate RSA key";
        doc = "When combined with --generate-privkey";
    };
    
    flag = {
        name        = real;
        value       = r;
        descrip     = "real paths";
        doc         = '';
    };
    
    main = {
        main-type    = for-each;
        handler-proc = check_a_file;
        handler-type = name;
    };
    no-xlate = anything;
    

    chk.c:

    #include "ck-opts.c"
    
    int check_a_file(char const * fname)
    {
          return 0;
    }
    

    generate and compile as in:

    autogen ck-opts.def
    gcc -O0 -ggdb3 -gdwarf-2 -o chk chk.c $(
        autoopts-config cflags static-libs)
    

    and finally:

     ./chk --help
    

    Once that help output reproduces the problem, then send the ck-opts.def file.

     
  • Nikos Mavrogiannopoulos

    It's quite long:

    AutoGen Definitions options;
    prog-name     = certtool;
    prog-title    = "GnuTLS certificate tool";
    prog-desc     = "Manipulate certificates and private keys.";
    detail    = "Tool to parse and generate X.509 certificates, requests and private keys.
    It can be used interactively or non interactively by
    specifying the template command line option.
    
    The tool accepts files or URLs supported by GnuTLS. In case PIN is required for the URL
    access you can provide it using the environment variables GNUTLS_PIN and GNUTLS_SO_PIN.
    ";
    short-usage   = "certtool [options]\ncerttool --help for usage instructions.\n";
    explain       = "";
    
    prog-group      = GnuTLS;
    gnu-usage;
    disable-save;
    long-opts;
    version         = "@VERSION@";
    no-misuse-usage;
    
    argument    = "[ <file-name> ... ]";
    
    flag = {
        name      = generate-proxy;
        descrip   = "Generates a proxy certificate";
        doc = "";
    };
    
    flag = {
        name      = generate-crl;
        descrip   = "Generate a CRL";
        doc = "This option generates a CRL. When combined with --load-crl it would use the loaded CRL as base for the generated (i.e., all revoked certificates in the base will be copied to the new CRL).";
    };
    
    flag = {
        name      = provable;
        descrip   = "Generate a private key or parameters from a seed using a provable method";
        doc = "This will use the FIPS-186-4 algorithms for provable key generation. You may specify --seed or allow GnuTLS to generate one (recommended). This option can be combined with --generate-privkey or --generate-dh-params.";
    };
    
    flag = {
        name      = verify-provable-privkey;
        descrip   = "Verify a private key generated from a seed using a provable method";
        doc = "This will use the FIPS-186-4 algorithms for provable key generation. You may specify --seed or use the seed stored in the private key structure.";
    };
    
    flag = {
        name      = seed;
        descrip   = "When generating a private key use the given hex-encoded seed";
        arg-type  = string;
        doc = "";
    };
    
    flag = {
        name      = load-data;
        descrip   = "Loads auxilary data";
        arg-type  = string;
        doc = "";
    };
    
    flag = {
        name      = password;
        arg-type  = string;
        descrip   = "Password to use";
        doc   = "You can use this option to specify the password in the command line instead of reading it from the tty. Note, that the command line arguments are available for view in others in the system. Specifying password as '' is the same as specifying no password.";
    };
    
    flag = {
        name      = null-password;
        descrip   = "Enforce a NULL password";
        doc   = "This option enforces a NULL password. This is different than the empty or no password in schemas like PKCS #8.";
    };
    
    flag = {
        name      = empty-password;
        descrip   = "Enforce an empty password";
        doc   = "This option enforces an empty password. This is different than the NULL or no password in schemas like PKCS #8.";
    };
    
    flag = {
        name      = hex-numbers;
        descrip   = "Print big number in an easier format to parse";
        doc   = "";
    };
    
    flag = {
        name      = cprint;
        descrip   = "In certain operations it prints the information in C-friendly format";
        doc   = "In certain operations it prints the information in C-friendly format, suitable for including into C programs.";
    };
    
    flag = {
        name      = certificate-info;
        value     = i;
        descrip   = "Print information on the given certificate";
        doc       = "";
    };
    
    flag = {
        name      = fingerprint;
        descrip   = "Print the fingerprint of the given certificate";
        doc       = "This is a simple hash of the DER encoding of the certificate. It can be combined with the --hash parameter. However, it is recommended for identification to use the key-id which depends only on the certificate's key.";
    };
    
    flag = {
        name      = key-id;
        descrip   = "Print the key ID of the given certificate";
        doc       = "This is a hash of the public key of the given certificate. It identifies the key uniquely, remains the same on a certificate renewal and depends only on signed fields of the certificate.";
    };
    
    flag = {
        name      = certificate-pubkey;
        descrip   = "Print certificate's public key";
        doc       = "";
    };
    
    flag = {
        name      = pgp-certificate-info;
        descrip   = "Print information on the given OpenPGP certificate";
        doc       = "";
    };
    
    flag = {
        name      = pgp-ring-info;
        descrip   = "Print information on the given OpenPGP keyring structure";
        doc       = "";
    };
    
    flag = {
        name      = crl-info;
        value     = l;
        descrip   = "Print information on the given CRL structure";
        doc       = "";
    };
    
    flag = {
        name      = crq-info;
        descrip   = "Print information on the given certificate request";
        doc       = "";
    };
    
    flag = {
        name      = no-crq-extensions;
        descrip   = "Do not use extensions in certificate requests";
        doc       = "";
    };
    
    flag = {
        name      = p12-info;
        descrip   = "Print information on a PKCS #12 structure";
        doc       = "This option will dump the contents and print the metadata of the provided PKCS #12 structure.";
    };
    
    flag = {
        name      = p12-name;
        arg-type  = string;
        descrip   = "The PKCS #12 friendly name to use";
        doc = "The name to be used for the primary certificate and private key in a PKCS #12 file.";
    };
    
    flag = {
        name      = key-info;
        value     = k;
        descrip   = "Print information on a private key";
        doc = "";
    };
    
    flag = {
        name      = pgp-key-info;
        descrip   = "Print information on an OpenPGP private key";
        doc = "";
    };
    
    flag = {
        name      = to-p8;
        descrip   = "Generate a PKCS #8 structure";
        doc = "";
    };
    
    flag = {
        name      = pkcs8;
        value     = 8;
        descrip   = "Use PKCS #8 format for private keys";
        doc = "";
    };
    
    flag = {
        name      = rsa;
        descrip   = "Generate RSA key";
        doc = "When combined with --generate-privkey generates an RSA private key.";
    };
    
    flag = {
        name      = dsa;
        descrip   = "Generate DSA key";
        doc = "When combined with --generate-privkey generates a DSA private key.";
    };
    
    flag = {
        name      = ecc;
        descrip   = "Generate ECC (ECDSA) key";
        doc = "When combined with --generate-privkey generates an elliptic curve private key to be used with ECDSA.";
    };
    
    flag = {
        name      = ecdsa;
        aliases   = ecc;
    };
    
    flag = {
        name      = hash;
        arg-type  = string;
        descrip   = "Hash algorithm to use for signing";
        doc = "Available hash functions are SHA1, RMD160, SHA256, SHA384, SHA512.";
    };
    
    flag = {
        name      = inder;
        descrip   = "Use DER format for input certificates, private keys, and DH parameters ";
        disabled;
        disable   = "no";
        doc       = "The input files will be assumed to be in DER or RAW format. 
    Unlike options that in PEM input would allow multiple input data (e.g. multiple 
    certificates), when reading in DER format a single data structure is read.";
    };
    
    flag = {
        name      = inraw;
        aliases   = inder;
    };
    
    flag = {
        name      = outder;
        descrip   = "Use DER format for output certificates, private keys, and DH parameters";
        disabled;
        disable   = "no";
        doc       = "The output will be in DER or RAW format.";
    };
    
    flag = {
        name      = outraw;
        aliases   = outder;
    };
    
    flag = {
        name      = bits;
        arg-type  = number;
        descrip   = "Specify the number of bits for key generate";
        doc      = "";
    };
    
    flag = {
        name      = curve;
        arg-type  = string;
        descrip   = "Specify the curve used for EC key generation";
        doc      = "Supported values are secp192r1, secp224r1, secp256r1, secp384r1 and secp521r1.";
    };
    
    flag = {
        name      = sec-param;
        arg-type  = string;
        arg-name  = "Security parameter";
        descrip   = "Specify the security level [low, legacy, medium, high, ultra]";
        doc      = "This is alternative to the bits option.";
    };
    
    flag = {
        name      = disable-quick-random;
        descrip   = "No effect";
        doc      = "";
    };
    
    flag = {
        name      = template;
        arg-type  = string;
        descrip   = "Template file to use for non-interactive operation";
        doc   = "";
    };
    
    flag = {
        name      = stdout-info;
        descrip   = "Print information to stdout instead of stderr";
        doc = "";
    };
    
    flag = {
        name      = ask-pass;
        disabled;
        descrip   = "Enable interaction for entering password when in batch mode.";
        doc   = "This option will enable interaction to enter password when in batch mode. That is useful when the template option has been specified.";
    };
    
    flag = {
        name      = pkcs-cipher;
        arg-type  = string;
        arg-name  = "Cipher";
        descrip   = "Cipher to use for PKCS #8 and #12 operations";
        doc   = "Cipher may be one of 3des, 3des-pkcs12, aes-128, aes-192, aes-256, rc2-40, arcfour.";
    };
    
    flag = {
        name      = provider;
        arg-type  = string;
        descrip   = "Specify the PKCS #11 provider library";
        doc      = "This will override the default options in /etc/gnutls/pkcs11.conf";
    };
    
    main = {
        main-type    = for-each;
        handler-proc = check_a_file;
        handler-type = name;
    };
    no-xlate = anything;
    
     
  • Bruce Korb

    Bruce Korb - 2016-04-20

    "quite long" is required. That is the source of the problem. The macro:

    define IS_GRAPHIC_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00004000)

    yields "true" for the value of 4130 for "c". The option that triggers this is the 38-th (number 37) and it happens when there is at least one short option and at least 33 options without short variants. I never tested that :) Thank you. If you add about 10 short options, the problem will go away. OK, I'll fix the issue.

     
  • Bruce Korb

    Bruce Korb - 2016-04-20
    • status: open --> pending
     
  • Bruce Korb

    Bruce Korb - 2016-04-20

    Patch has been applied:

    $ ./bad --help| sed 7,40d
    certtool - GnuTLS certificate tool
    Usage:  bad [ -<flag> [<val>] | --<name>[{=| }<val>] ]... \
                [ <file-name> ... ]
    
       --generate-proxy       Generates a proxy certificate
       --generate-crl         Generate a CRL
       [...]
       --outraw               an alias for the 'outder' option
       --bits=num             Specify the number of bits for key generate
       --curve=str            Specify the curve used for EC key generation
       --sec-param=str        Specify the security level [low, legacy, medium, high, ultra]
       --disable-quick-random  No effect
       --template=str         Template file to use for non-interactive operation
       --stdout-info          Print information to stdout instead of stderr
       --ask-pass             Enable interaction for entering password when in batch mode.
       --pkcs-cipher=str      Cipher to use for PKCS #8 and #12 operations
       --provider=str         Specify the PKCS #11 provider library
    -v, --version[=arg]        output version information and exit
    -?, --help                 display extended usage information and exit
    -!,  --- help           display extended usage information and exit
    
     
  • Nikos Mavrogiannopoulos

    Thank you!

     
  • Bruce Korb

    Bruce Korb - 2020-09-14
    • status: pending --> closed
     
  • Bruce Korb

    Bruce Korb - 2020-09-14

    fixed

     

Log in to post a comment.