catopen(3): align returned errors with IEEE Std 1003.1™-2024

- Invalid/non-existent/unable to use message catalog file should result in
  ENOENT, and not in EFTYPE.
- Added detection of several cases of wrong file format due to length [*].
- Update man page.

* Based on the original patch from PR.

PR:	172805
Reviewed by:	emaste
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Differential revision:	https://reviews.freebsd.org/D47413
This commit is contained in:
Konstantin Belousov 2024-11-03 14:50:32 +02:00
parent 79c342aaf8
commit 1176390d2d
2 changed files with 26 additions and 17 deletions

View file

@ -130,16 +130,17 @@ Otherwise, (nl_catd) -1 is returned and
is set to indicate the error.
.Sh ERRORS
.Bl -tag -width Er
.It Bq Er EINVAL
Argument
.Fa name
does not point to a valid message catalog, or catalog is corrupt.
.It Bq Er ENAMETOOLONG
An entire path to the message catalog exceeded 1024 characters.
.It Bq Er ENOENT
The named message catalog does not exists, or the
Argument
.Fa name
argument points to an empty string.
does not point to a valid message catalog name,
or it points to an empty string.
.It Bq Er ENOENT
The named message catalog does not exist.
.It Bq Er ENOENT
The named message catalog file is in wrong format.
.It Bq Er ENOMEM
Insufficient memory is available.
.El

View file

@ -136,7 +136,7 @@ __catopen_l(const char *name, int type, locale_t locale)
/* sanity checking */
if (name == NULL || *name == '\0')
NLRETERR(EINVAL);
NLRETERR(ENOENT);
if (strchr(name, '/') != NULL)
/* have a pathname */
@ -390,7 +390,7 @@ load_msgcat(const char *path, const char *name, const char *lang)
struct catentry *np;
void *data;
char *copy_path, *copy_name, *copy_lang;
int fd;
int fd, saved_errno;
/* path/name will never be NULL here */
@ -414,9 +414,17 @@ load_msgcat(const char *path, const char *name, const char *lang)
}
if (_fstat(fd, &st) != 0) {
saved_errno = errno;
_close(fd);
SAVEFAIL(name, lang, EFTYPE);
NLRETERR(EFTYPE);
SAVEFAIL(name, lang, saved_errno);
NLRETERR(saved_errno);
}
/* The file is too small to contain a _NLS_MAGIC. */
if (st.st_size < sizeof(u_int32_t)) {
_close(fd);
SAVEFAIL(name, lang, ENOENT);
NLRETERR(ENOENT);
}
/*
@ -426,13 +434,13 @@ load_msgcat(const char *path, const char *name, const char *lang)
*/
if (st.st_size > SIZE_T_MAX) {
_close(fd);
SAVEFAIL(name, lang, EFBIG);
NLRETERR(EFBIG);
SAVEFAIL(name, lang, ENOENT);
NLRETERR(ENOENT);
}
if ((data = mmap(0, (size_t)st.st_size, PROT_READ,
MAP_FILE|MAP_SHARED, fd, (off_t)0)) == MAP_FAILED) {
int saved_errno = errno;
data = mmap(0, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
if (data == MAP_FAILED) {
saved_errno = errno;
_close(fd);
SAVEFAIL(name, lang, saved_errno);
NLRETERR(saved_errno);
@ -442,8 +450,8 @@ load_msgcat(const char *path, const char *name, const char *lang)
if (ntohl((u_int32_t)((struct _nls_cat_hdr *)data)->__magic) !=
_NLS_MAGIC) {
munmap(data, (size_t)st.st_size);
SAVEFAIL(name, lang, EFTYPE);
NLRETERR(EFTYPE);
SAVEFAIL(name, lang, ENOENT);
NLRETERR(ENOENT);
}
copy_name = strdup(name);