#1037929 git grep fails with "Invalid collation character" for valid collation sequences in []

Package:
git
Source:
git
Description:
fast, scalable, distributed revision control system
Submitter:
наб
Date:
2023-06-14 13:54:06 UTC
Severity:
normal
#1037929#5
Date:
2023-06-14 13:26:09 UTC
From:
To:
Dear Maintainer,

  $ git grep '[а-я]'
  fatal: command line, '[а-я]': Invalid collation character
and even
  nabijaczleweli@tarta:~/code/voreutils$ locale
  LANG=en_GB.UTF-8
  LANGUAGE=en_GB:en
  LC_CTYPE="en_GB.UTF-8"
  LC_NUMERIC="en_GB.UTF-8"
  LC_TIME="en_GB.UTF-8"
  LC_COLLATE="en_GB.UTF-8"
  LC_MONETARY="en_GB.UTF-8"
  LC_MESSAGES="en_GB.UTF-8"
  LC_PAPER="en_GB.UTF-8"
  LC_NAME="en_GB.UTF-8"
  LC_ADDRESS="en_GB.UTF-8"
  LC_TELEPHONE="en_GB.UTF-8"
  LC_MEASUREMENT="en_GB.UTF-8"
  LC_IDENTIFICATION="en_GB.UTF-8"
  LC_ALL=
  $ git grep '[а-я]'
  fatal: command line, '[а-я]': Invalid collation character
  $ LC_ALL=ru_RU.UTF-8 locale
  LANG=en_GB.UTF-8
  LANGUAGE=en_GB:en
  LC_CTYPE="ru_RU.UTF-8"
  LC_NUMERIC="ru_RU.UTF-8"
  LC_TIME="ru_RU.UTF-8"
  LC_COLLATE="ru_RU.UTF-8"
  LC_MONETARY="ru_RU.UTF-8"
  LC_MESSAGES="ru_RU.UTF-8"
  LC_PAPER="ru_RU.UTF-8"
  LC_NAME="ru_RU.UTF-8"
  LC_ADDRESS="ru_RU.UTF-8"
  LC_TELEPHONE="ru_RU.UTF-8"
  LC_MEASUREMENT="ru_RU.UTF-8"
  LC_IDENTIFICATION="ru_RU.UTF-8"
  LC_ALL=ru_RU.UTF-8
  $ LC_ALL=ru_RU.UTF-8 git grep '[а-я]'
  fatal: command line, '[а-я]': Invalid collation character

This ought to match the entire modern russian alphabet,
and correctly does so under GNU grep and glibc regcomp(3)
on bookworm and sid.

I don't really see how а or я are "invalid" here;
oddly, git grep does accept '[ая]' &c.

Best,
наб

#1037929#10
Date:
2023-06-14 13:52:21 UTC
From:
To:
  $ cat dumpregex.c
  #define _GNU_SOURCE
  #include <dlfcn.h>
  #include <locale.h>
  #include <regex.h>
  #include <stdio.h>

  int regcomp(regex_t * restrict preg, const char * restrict regex, int cflags) {
  	fprintf(stderr, "LC_ALL=%s\n", setlocale(LC_ALL, NULL));
  	fprintf(stderr, "LC_ADDRESS=%s\n", setlocale(LC_ADDRESS, NULL));
  	fprintf(stderr, "LC_COLLATE=%s\n", setlocale(LC_COLLATE, NULL));
  	fprintf(stderr, "LC_CTYPE=%s\n", setlocale(LC_CTYPE, NULL));
  	fprintf(stderr, "LC_IDENTIFICATION=%s\n", setlocale(LC_IDENTIFICATION, NULL));
  	fprintf(stderr, "LC_MEASUREMENT=%s\n", setlocale(LC_MEASUREMENT, NULL));
  	fprintf(stderr, "LC_MESSAGES=%s\n", setlocale(LC_MESSAGES, NULL));
  	fprintf(stderr, "LC_MONETARY=%s\n", setlocale(LC_MONETARY, NULL));
  	fprintf(stderr, "LC_NAME=%s\n", setlocale(LC_NAME, NULL));
  	fprintf(stderr, "LC_NUMERIC=%s\n", setlocale(LC_NUMERIC, NULL));
  	fprintf(stderr, "LC_PAPER=%s\n", setlocale(LC_PAPER, NULL));
  	fprintf(stderr, "LC_TELEPHONE=%s\n", setlocale(LC_TELEPHONE, NULL));
  	fprintf(stderr, "LC_TIME=%s\n", setlocale(LC_TIME, NULL));

  	fprintf(stderr, "regcomp(%p, '%s', %d %s %s %s %s)=", preg, regex, cflags, (cflags & REG_EXTENDED) ? "REG_EXTENDED" : "",
  	        (cflags & REG_ICASE) ? "REG_ICASE" : "", (cflags & REG_NEWLINE) ? "REG_NEWLINE" : "", (cflags & REG_NOSUB) ? "REG_NOSUB" : "");
  	int ret = ((int (*)(regex_t * restrict preg, const char * restrict regex, int cflags))dlsym(RTLD_NEXT, __func__))(preg, regex, cflags);
  	fprintf(stderr, "%d\n", ret);
  	return ret;
  }
  $ cc dumpregex.c -ldl -shared -odumpregex.so
  $ LD_PRELOAD=./dumpregex.so git grep '[а-я]'
and indeed
  $ ltrace -esetlocale -e newlocale git grep '[а-я]'
  git->setlocale(LC_CTYPE, "")                                                                              = "en_GB.UTF-8"
  git->setlocale(LC_MESSAGES, "")                                                                           = "en_GB.UTF-8"
  git->setlocale(LC_TIME, "")                                                                               = "en_GB.UTF-8"
  fatal: command line, '[а-я]': Invalid collation character
  +++ exited (status 128) +++

Why on earth would you do this or want that?

Best,
наб