diff options
Diffstat (limited to 'g10')
-rw-r--r-- | g10/call-agent.c | 8 | ||||
-rw-r--r-- | g10/card-util.c | 28 | ||||
-rw-r--r-- | g10/cipher.c | 2 | ||||
-rw-r--r-- | g10/getkey.c | 15 | ||||
-rw-r--r-- | g10/gpg.c | 6 | ||||
-rw-r--r-- | g10/gpg.h | 13 | ||||
-rw-r--r-- | g10/gpgcompose.c | 2 | ||||
-rw-r--r-- | g10/keygen.c | 11 | ||||
-rw-r--r-- | g10/keyid.c | 48 | ||||
-rw-r--r-- | g10/keylist.c | 43 | ||||
-rw-r--r-- | g10/main.h | 4 | ||||
-rw-r--r-- | g10/options.h | 1 | ||||
-rw-r--r-- | g10/sig-check.c | 6 | ||||
-rw-r--r-- | g10/tdbdump.c | 14 | ||||
-rw-r--r-- | g10/tofu.c | 16 | ||||
-rw-r--r-- | g10/trustdb.c | 6 |
16 files changed, 171 insertions, 52 deletions
diff --git a/g10/call-agent.c b/g10/call-agent.c index 545b2448a..684771b75 100644 --- a/g10/call-agent.c +++ b/g10/call-agent.c @@ -1474,7 +1474,7 @@ agent_probe_any_secret_key (ctrl_t ctrl, kbnode_t keyblock) char *p; kbnode_t kbctx, node; int nkeys; - unsigned char grip[20]; + unsigned char grip[KEYGRIP_LEN]; err = start_agent (ctrl, 0); if (err) @@ -1854,10 +1854,16 @@ agent_pksign (ctrl_t ctrl, const char *cache_nonce, snprintf (line, sizeof line, "PKSIGN%s%s", cache_nonce? " -- ":"", cache_nonce? cache_nonce:""); + + if (DBG_CLOCK) + log_clock ("enter signing"); err = assuan_transact (agent_ctx, line, put_membuf_cb, &data, default_inq_cb, &dfltparm, NULL, NULL); + if (DBG_CLOCK) + log_clock ("leave signing"); + if (err) xfree (get_membuf (&data, NULL)); else diff --git a/g10/card-util.c b/g10/card-util.c index a396b7df4..8a03a26cf 100644 --- a/g10/card-util.c +++ b/g10/card-util.c @@ -212,6 +212,7 @@ get_manufacturer (unsigned int no) case 0x000A: return "Dangerous Things"; case 0x002A: return "Magrathea"; + case 0x0042: return "GnuPG e.V."; case 0x1337: return "Warsaw Hackerspace"; case 0x2342: return "warpzone"; /* hackerspace Muenster. */ @@ -1121,7 +1122,8 @@ change_cafpr (int fprno) char *data; const char *s; int i, c, rc; - unsigned char fpr[20]; + unsigned char fpr[MAX_FINGERPRINT_LEN]; + int fprlen; data = cpr_get ("cardedit.change_cafpr", _("CA fingerprint: ")); if (!data) @@ -1129,7 +1131,7 @@ change_cafpr (int fprno) trim_spaces (data); cpr_kill_prompt (); - for (i=0, s=data; i < 20 && *s; ) + for (i=0, s=data; i < MAX_FINGERPRINT_LEN && *s; ) { while (spacep(s)) s++; @@ -1143,8 +1145,9 @@ change_cafpr (int fprno) fpr[i++] = c; s += 2; } + fprlen = i; xfree (data); - if (i != 20 || *s) + if ((fprlen != 20 && fprlen != 32) || *s) { tty_printf (_("Error: invalid formatted fingerprint.\n")); return -1; @@ -1152,7 +1155,7 @@ change_cafpr (int fprno) rc = agent_scd_setattr (fprno==1?"CA-FPR-1": fprno==2?"CA-FPR-2": - fprno==3?"CA-FPR-3":"x", fpr, 20, NULL ); + fprno==3?"CA-FPR-3":"x", fpr, fprlen, NULL ); if (rc) log_error ("error setting cafpr: %s\n", gpg_strerror (rc)); write_sc_op_status (rc); @@ -1314,12 +1317,11 @@ show_keysize_warning (void) return; shown = 1; tty_printf - (_("Note: There is no guarantee that the card " - "supports the requested size.\n" - " If the key generation does not succeed, " - "please check the\n" - " documentation of your card to see what " - "sizes are allowed.\n")); + (_("Note: There is no guarantee that the card supports the requested\n" + " key type or size. If the key generation does not succeed,\n" + " please check the documentation of your card to see which\n" + " key types and sizes are supported.\n") + ); } @@ -1379,8 +1381,12 @@ ask_card_keyattr (int keyno, unsigned int nbits) } else { + char name[30]; + + snprintf (name, sizeof name, "rsa%u", req_nbits); tty_printf (_("The card will now be re-configured" - " to generate a key of %u bits\n"), req_nbits); + " to generate a key of type: %s\n"), + name); show_keysize_warning (); return req_nbits; } diff --git a/g10/cipher.c b/g10/cipher.c index 655937f07..7031d93eb 100644 --- a/g10/cipher.c +++ b/g10/cipher.c @@ -66,7 +66,7 @@ write_header( cipher_filter_context_t *cfx, IOBUF a ) { char buf[20]; - sprintf (buf, "%d %d", ed.mdc_method, cfx->dek->algo); + snprintf (buf, sizeof buf, "%d %d", ed.mdc_method, cfx->dek->algo); write_status_text (STATUS_BEGIN_ENCRYPTION, buf); } diff --git a/g10/getkey.c b/g10/getkey.c index f73e44326..0a741cb2d 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -144,7 +144,7 @@ static int lookup (ctrl_t ctrl, getkey_ctx_t ctx, int want_secret, kbnode_t *ret_keyblock, kbnode_t *ret_found_key); static kbnode_t finish_lookup (kbnode_t keyblock, unsigned int req_usage, int want_exact, - unsigned int *r_flags); + int want_secret, unsigned int *r_flags); static void print_status_key_considered (kbnode_t keyblock, unsigned int flags); @@ -1735,7 +1735,7 @@ get_pubkey_fromfile (ctrl_t ctrl, PKT_public_key *pk, const char *fname) /* Warning: node flag bits 0 and 1 should be preserved by * merge_selfsigs. FIXME: Check whether this still holds. */ merge_selfsigs (ctrl, keyblock); - found_key = finish_lookup (keyblock, pk->req_usage, 0, &infoflags); + found_key = finish_lookup (keyblock, pk->req_usage, 0, 0, &infoflags); print_status_key_considered (keyblock, infoflags); if (found_key) pk_from_block (pk, keyblock, found_key); @@ -3486,7 +3486,7 @@ merge_selfsigs (ctrl_t ctrl, kbnode_t keyblock) */ static kbnode_t finish_lookup (kbnode_t keyblock, unsigned int req_usage, int want_exact, - unsigned int *r_flags) + int want_secret, unsigned int *r_flags) { kbnode_t k; @@ -3628,6 +3628,13 @@ finish_lookup (kbnode_t keyblock, unsigned int req_usage, int want_exact, continue; } + if (want_secret && agent_probe_secret_key (NULL, pk)) + { + if (DBG_LOOKUP) + log_debug ("\tno secret key\n"); + continue; + } + if (DBG_LOOKUP) log_debug ("\tsubkey might be fine\n"); /* In case a key has a timestamp of 0 set, we make sure @@ -3815,7 +3822,7 @@ lookup (ctrl_t ctrl, getkey_ctx_t ctx, int want_secret, * merge_selfsigs. */ merge_selfsigs (ctrl, keyblock); found_key = finish_lookup (keyblock, ctx->req_usage, ctx->exact, - &infoflags); + want_secret, &infoflags); print_status_key_considered (keyblock, infoflags); if (found_key) { @@ -197,6 +197,7 @@ enum cmd_and_opt_values oWithSubkeyFingerprint, oWithICAOSpelling, oWithKeygrip, + oWithKeyScreening, oWithSecret, oWithWKDHash, oWithColons, @@ -785,6 +786,7 @@ static ARGPARSE_OPTS opts[] = { ARGPARSE_s_n (oWithSubkeyFingerprint, "with-subkey-fingerprints", "@"), ARGPARSE_s_n (oWithICAOSpelling, "with-icao-spelling", "@"), ARGPARSE_s_n (oWithKeygrip, "with-keygrip", "@"), + ARGPARSE_s_n (oWithKeyScreening,"with-key-screening", "@"), ARGPARSE_s_n (oWithSecret, "with-secret", "@"), ARGPARSE_s_n (oWithWKDHash, "with-wkd-hash", "@"), ARGPARSE_s_n (oWithKeyOrigin, "with-key-origin", "@"), @@ -2737,6 +2739,10 @@ main (int argc, char **argv) opt.with_keygrip = 1; break; + case oWithKeyScreening: + opt.with_key_screening = 1; + break; + case oWithSecret: opt.with_secret = 1; break; @@ -38,14 +38,15 @@ #define MAX_EXTERN_MPI_BITS 16384 /* The maximum length of a binary fingerprints. This is used to - provide a static buffer and will be increased if we need to support - longer fingerprints. - Warning: At some places we still use 20 instead of this macro. */ -#define MAX_FINGERPRINT_LEN 20 + * provide a static buffer and will be increased if we need to support + * longer fingerprints. Warning: At some places we have some + * assumption on a 20 byte fingerprint. + * Watch out for FIXME(fingerprint) */ +#define MAX_FINGERPRINT_LEN 32 /* The maximum length of a formatted fingerprint as returned by - format_hexfingerprint(). */ -#define MAX_FORMATTED_FINGERPRINT_LEN 50 + * format_hexfingerprint(). */ +#define MAX_FORMATTED_FINGERPRINT_LEN 59 /* diff --git a/g10/gpgcompose.c b/g10/gpgcompose.c index 2b42bfbf9..8c156d279 100644 --- a/g10/gpgcompose.c +++ b/g10/gpgcompose.c @@ -2746,7 +2746,7 @@ literal_name (const char *option, int argc, char *argv[], void *cookie) { struct litinfo *li = cookie; - if (argc <= 1) + if (argc <= 0) log_fatal ("Usage: %s NAME\n", option); if (strlen (argv[0]) > 255) diff --git a/g10/keygen.c b/g10/keygen.c index 38686b213..12815744f 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -46,11 +46,10 @@ #include "../common/mbox-util.h" -/* The default algorithms. If you change them remember to change them - also in gpg.c:gpgconf_list. You should also check that the value +/* The default algorithms. If you change them, you should ensure the value is inside the bounds enforced by ask_keysize and gen_xxx. See also get_keysize_range which encodes the allowed ranges. */ -#define DEFAULT_STD_KEY_PARAM "rsa2048/cert,sign+rsa2048/encr" +#define DEFAULT_STD_KEY_PARAM "rsa3072/cert,sign+rsa3072/encr" #define FUTURE_STD_KEY_PARAM "ed25519/cert,sign+cv25519/encr" /* When generating keys using the streamlined key generation dialog, @@ -91,7 +90,7 @@ enum para_name { pHANDLE, pKEYSERVER, pKEYGRIP, - pSUBKEYGRIP, + pSUBKEYGRIP }; struct para_data_s { @@ -1624,7 +1623,7 @@ gen_rsa (int algo, unsigned int nbits, KBNODE pub_root, if (nbits < 1024) { - nbits = 2048; + nbits = 3072; log_info (_("keysize invalid; using %u bits\n"), nbits ); } else if (nbits > maxsize) @@ -2093,7 +2092,7 @@ get_keysize_range (int algo, unsigned int *min, unsigned int *max) default: *min = opt.compliance == CO_DE_VS ? 2048: 1024; *max = 4096; - def = 2048; + def = 3072; break; } diff --git a/g10/keyid.c b/g10/keyid.c index d733156f8..78a5b0b70 100644 --- a/g10/keyid.c +++ b/g10/keyid.c @@ -73,7 +73,7 @@ pubkey_letter( int algo ) is copied to the supplied buffer up a length of BUFSIZE-1. Examples for the output are: - "rsa2048" - RSA with 2048 bit + "rsa3072" - RSA with 3072 bit "elg1024" - Elgamal with 1024 bit "ed25519" - ECC using the curve Ed25519. "E_1.2.3.4" - ECC using the unsupported curve with OID "1.2.3.4". @@ -83,7 +83,7 @@ pubkey_letter( int algo ) If the option --legacy-list-mode is active, the output use the legacy format: - "2048R" - RSA with 2048 bit + "3072R" - RSA with 3072 bit "1024g" - Elgamal with 1024 bit "256E" - ECDSA using a curve with 256 bit @@ -835,8 +835,22 @@ format_hexfingerprint (const char *fingerprint, char *buffer, size_t buflen) /* Half way through we add a second space. */ + 1); } + else if (hexlen == 64 || hexlen == 50) /* v5 fingerprint */ + { + /* The v5 fingerprint is commonly printed truncated to 25 + * octets. We accept the truncated as well as the full hex + * version here and format it like this: + * B2CCB6 838332 5D61BA C50F9F 5E CD21A8 0AC8C5 2565C8 C52565 + */ + hexlen = 50; + space = 8 * 6 + 2 + 8 + 1; + } else /* Other fingerprint versions - print as is. */ { + /* We truncated here so that we do not need to provide a buffer + * of a length which is in reality never used. */ + if (hexlen > MAX_FORMATTED_FINGERPRINT_LEN - 1) + hexlen = MAX_FORMATTED_FINGERPRINT_LEN - 1; space = hexlen + 1; } @@ -849,7 +863,7 @@ format_hexfingerprint (const char *fingerprint, char *buffer, size_t buflen) { for (i = 0, j = 0; i < 40; i ++) { - if (i && i % 4 == 0) + if (i && !(i % 4)) buffer[j ++] = ' '; if (i == 40 / 2) buffer[j ++] = ' '; @@ -859,9 +873,29 @@ format_hexfingerprint (const char *fingerprint, char *buffer, size_t buflen) buffer[j ++] = 0; log_assert (j == space); } + else if (hexlen == 50) /* v5 fingerprint */ + { + for (i=j=0; i < 24; i++) + { + if (i && !(i % 6)) + buffer[j++] = ' '; + buffer[j++] = fingerprint[i]; + } + buffer[j++] = ' '; + buffer[j++] = fingerprint[i++]; + buffer[j++] = fingerprint[i++]; + for (; i < 50; i++) + { + if (!((i-26) % 6)) + buffer[j++] = ' '; + buffer[j++] = fingerprint[i]; + } + buffer[j++] = 0; + log_assert (j == space); + } else { - strcpy (buffer, fingerprint); + mem2str (buffer, fingerprint, space); } return buffer; @@ -959,18 +993,18 @@ gpg_error_t hexkeygrip_from_pk (PKT_public_key *pk, char **r_grip) { gpg_error_t err; - unsigned char grip[20]; + unsigned char grip[KEYGRIP_LEN]; *r_grip = NULL; err = keygrip_from_pk (pk, grip); if (!err) { - char * buf = xtrymalloc (20*2+1); + char * buf = xtrymalloc (KEYGRIP_LEN * 2 + 1); if (!buf) err = gpg_error_from_syserror (); else { - bin2hex (grip, 20, buf); + bin2hex (grip, KEYGRIP_LEN, buf); *r_grip = buf; } } diff --git a/g10/keylist.c b/g10/keylist.c index 86d1c564f..bcbad450a 100644 --- a/g10/keylist.c +++ b/g10/keylist.c @@ -45,6 +45,7 @@ #include "../common/zb32.h" #include "tofu.h" #include "../common/compliance.h" +#include "../common/pkscreening.h" static void list_all (ctrl_t, int, int); @@ -696,6 +697,37 @@ print_key_data (PKT_public_key * pk) } } + +/* Various public key screenings. (Right now just ROCA). With + * COLON_MODE set the output is formatted for use in the compliance + * field of a colon listing. + */ +static void +print_pk_screening (PKT_public_key *pk, int colon_mode) +{ + gpg_error_t err; + + if (is_RSA (pk->pubkey_algo) && pubkey_get_npkey (pk->pubkey_algo)) + { + err = screen_key_for_roca (pk->pkey[0]); + if (!err) + ; + else if (gpg_err_code (err) == GPG_ERR_TRUE) + { + if (colon_mode) + es_fprintf (es_stdout, colon_mode > 1? " %d":"%d", 6001); + else + es_fprintf (es_stdout, + " Screening: ROCA vulnerability detected\n"); + } + else if (!colon_mode) + es_fprintf (es_stdout, " Screening: [ROCA check failed: %s]\n", + gpg_strerror (err)); + } + +} + + static void print_capabilities (ctrl_t ctrl, PKT_public_key *pk, KBNODE keyblock) { @@ -922,6 +954,9 @@ list_keyblock_print (ctrl_t ctrl, kbnode_t keyblock, int secret, int fpr, if (opt.with_key_data) print_key_data (pk); + if (opt.with_key_screening) + print_pk_screening (pk, 0); + if (opt.with_key_origin && (pk->keyorg || pk->keyupdate || pk->updateurl)) { @@ -1063,6 +1098,8 @@ list_keyblock_print (ctrl_t ctrl, kbnode_t keyblock, int secret, int fpr, es_fprintf (es_stdout, " Keygrip = %s\n", hexgrip); if (opt.with_key_data) print_key_data (pk2); + if (opt.with_key_screening) + print_pk_screening (pk2, 0); } else if (opt.list_sigs && node->pkt->pkttype == PKT_SIGNATURE && !skip_sigs) @@ -1227,6 +1264,9 @@ print_compliance_flags (PKT_public_key *pk, gnupg_status_compliance_flag (CO_DE_VS)); any++; } + + if (opt.with_key_screening) + print_pk_screening (pk, 1+any); } @@ -1906,6 +1946,9 @@ print_card_serialno (const char *serialno) * pub dsa2048 2007-12-31 [SC] [expires: 2018-12-31] * 80615870F5BAD690333686D0F2AD85AC1E42B367 * + * pub rsa2048 2017-12-31 [SC] [expires: 2028-12-31] + * 80615870F5BAD690333686D0F2AD85AC1E42B3671122334455 + * * Some global options may result in a different output format. If * SECRET is set, "sec" or "ssb" is used instead of "pub" or "sub" and * depending on the value a flag character is shown: diff --git a/g10/main.h b/g10/main.h index 6c15a2a8d..4a8f8c32a 100644 --- a/g10/main.h +++ b/g10/main.h @@ -31,7 +31,9 @@ (i.e. uncompressed) rather than 1 (zip). However, the real world issues of speed and size come into play here. */ -#if GPG_USE_AES128 +#if GPG_USE_AES256 +# define DEFAULT_CIPHER_ALGO CIPHER_ALGO_AES256 +#elif GPG_USE_AES128 # define DEFAULT_CIPHER_ALGO CIPHER_ALGO_AES #elif GPG_USE_CAST5 # define DEFAULT_CIPHER_ALGO CIPHER_ALGO_CAST5 diff --git a/g10/options.h b/g10/options.h index 130bec84c..61f7403be 100644 --- a/g10/options.h +++ b/g10/options.h @@ -82,6 +82,7 @@ struct int with_fingerprint; /* Option --with-fingerprint active. */ int with_subkey_fingerprint; /* Option --with-subkey-fingerprint active. */ int with_keygrip; /* Option --with-keygrip active. */ + int with_key_screening;/* Option --with-key-screening active. */ int with_tofu_info; /* Option --with-tofu_info active. */ int with_secret; /* Option --with-secret active. */ int with_wkd_hash; /* Option --with-wkd-hash. */ diff --git a/g10/sig-check.c b/g10/sig-check.c index 23af12b2e..f8e366b7e 100644 --- a/g10/sig-check.c +++ b/g10/sig-check.c @@ -233,7 +233,7 @@ check_signature2 (ctrl_t ctrl, unsigned char *p, *buffer; size_t n, nbytes; int i; - char hashbuf[20]; + char hashbuf[20]; /* We use SHA-1 here. */ nbytes = 6; for (i=0; i < nsig; i++ ) @@ -510,7 +510,11 @@ check_signature_end_simple (PKT_public_key *pk, PKT_signature *sig, return GPG_ERR_GENERAL; /* Verify the signature. */ + if (DBG_CLOCK && sig->sig_class <= 0x01) + log_clock ("enter pk_verify"); rc = pk_verify( pk->pubkey_algo, result, sig->data, pk->pkey ); + if (DBG_CLOCK && sig->sig_class <= 0x01) + log_clock ("leave pk_verify"); gcry_mpi_release (result); if( !rc && sig->flags.unknown_critical ) diff --git a/g10/tdbdump.c b/g10/tdbdump.c index 5ea903f45..37bf78b80 100644 --- a/g10/tdbdump.c +++ b/g10/tdbdump.c @@ -129,7 +129,7 @@ import_ownertrust (ctrl_t ctrl, const char *fname ) char *p; size_t n, fprlen; unsigned int otrust; - byte fpr[20]; + byte fpr[MAX_FINGERPRINT_LEN]; int any = 0; int rc; @@ -171,7 +171,7 @@ import_ownertrust (ctrl_t ctrl, const char *fname ) continue; } fprlen = p - line; - if( fprlen != 32 && fprlen != 40 ) { + if( fprlen != 32 && fprlen != 40 && fprlen != 64) { log_error (_("error in '%s': %s\n"), fname, _("invalid fingerprint") ); continue; @@ -183,10 +183,12 @@ import_ownertrust (ctrl_t ctrl, const char *fname ) } if( !otrust ) continue; /* no otrust defined - no need to update or insert */ - /* convert the ascii fingerprint to binary */ - for(p=line, fprlen=0; fprlen < 20 && *p != ':'; p += 2 ) - fpr[fprlen++] = HEXTOBIN(p[0]) * 16 + HEXTOBIN(p[1]); - while (fprlen < 20) + /* Convert the ascii fingerprint to binary */ + for(p=line, fprlen=0; + fprlen < MAX_FINGERPRINT_LEN && *p != ':'; + p += 2 ) + fpr[fprlen++] = HEXTOBIN(p[0]) * 16 + HEXTOBIN(p[1]); + while (fprlen < MAX_FINGERPRINT_LEN) fpr[fprlen++] = 0; rc = tdbio_search_trust_byfpr (fpr, &rec); diff --git a/g10/tofu.c b/g10/tofu.c index c183fc665..e63e98932 100644 --- a/g10/tofu.c +++ b/g10/tofu.c @@ -2083,13 +2083,16 @@ build_conflict_set (ctrl_t ctrl, tofu_dbs_t dbs, * policy to ask due to a conflict. */ for (iter = conflict_set; iter; iter = iter->next) { + /* Fixme: Why the check against N+1? */ int l = strlen (iter->d); - if (!(l == 2 * MAX_FINGERPRINT_LEN - || l == 2 * MAX_FINGERPRINT_LEN + 1)) + if (!(l == 2 * 20 + || l == 2 * 20 + 1 + || l == 2 * 32 + || l == 2 * 32 + 1)) { log_error (_("TOFU db corruption detected.\n")); - print_further_info ("fingerprint '%s' is not %d characters long", - iter->d, 2 * MAX_FINGERPRINT_LEN); + print_further_info ("fingerprint '%s' is %d characters long", + iter->d, l); } if (l >= 1 && iter->d[l - 1] == '!') @@ -2469,10 +2472,11 @@ get_policy (ctrl_t ctrl, tofu_dbs_t dbs, PKT_public_key *pk, /* See if the key is signed by an ultimately trusted key. */ { int fingerprint_raw_len = strlen (fingerprint) / 2; - char fingerprint_raw[20]; + char fingerprint_raw[MAX_FINGERPRINT_LEN]; int len = 0; - if (fingerprint_raw_len != sizeof fingerprint_raw + /* FIXME(fingerprint) */ + if (fingerprint_raw_len != 20 /*sizeof fingerprint_raw */ || ((len = hex2bin (fingerprint, fingerprint_raw, fingerprint_raw_len)) != strlen (fingerprint))) diff --git a/g10/trustdb.c b/g10/trustdb.c index 92c1ca50a..0a98c129f 100644 --- a/g10/trustdb.c +++ b/g10/trustdb.c @@ -1505,6 +1505,10 @@ store_validation_status (ctrl_t ctrl, int depth, /* Returns a sanitized copy of the regexp (which might be "", but not NULL). */ #ifndef DISABLE_REGEX +/* Operator charactors except '.' and backslash. + See regex(7) on BSD. */ +#define REGEXP_OPERATOR_CHARS "^[$()|*+?{" + static char * sanitize_regexp(const char *old) { @@ -1544,7 +1548,7 @@ sanitize_regexp(const char *old) { if(!escaped && old[start]=='\\') escaped=1; - else if(!escaped && old[start]!='.') + else if (!escaped && strchr (REGEXP_OPERATOR_CHARS, old[start])) new[idx++]='\\'; else escaped=0; |