From: Pietro Monteiro Date: Fri, 30 Jan 2026 12:57:02 +0000 (-0500) Subject: libga68: Use the internal malloc for UTF-32 to UTF-8 conversion X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a2a7c49948ae75324c7fcb92719568a0928d1671;p=thirdparty%2Fgcc.git libga68: Use the internal malloc for UTF-32 to UTF-8 conversion _libga68_u32_to_u8 called free on the result buffer on error, but the buffer is allocated by the GC, so calling free on it is incorrect. Instead of using the GC, use the internal malloc because this is an internal function. Remove the resultbuf parameter from the _libga68_u32_to_u8 since all callers used NULL for it. Last but not least, return a null-terminated char* from _libga68_u32_to_u8. libga68/ChangeLog: * ga68-alloc.c (_libga68_realloc_internal): New function. * ga68-posix.c (_libga68_posixperror): Adjust calls to _libga68_u32_to_u8. (_libga68_posixfopen): Likewise. (_libga68_posixcreat): Likewise. (_libga68_posixgetenv): Likewise. (_libga68_posixfputs): Likewise. (_libga68_posixfconnect): Likewise. * ga68-unistr.c (_libga68_u32_to_u8): Use internal allocator. * ga68.h (_libga68_realloc_internal): New prototype. (_libga68_u32_to_u8): Update prototype. Signed-off-by: Pietro Monteiro --- diff --git a/libga68/ga68-alloc.c b/libga68/ga68-alloc.c index df8a8956c52..1edc148db69 100644 --- a/libga68/ga68-alloc.c +++ b/libga68/ga68-alloc.c @@ -42,6 +42,15 @@ _libga68_malloc_internal (size_t size) return res; } +void * +_libga68_realloc_internal (void *ptr, size_t size) +{ + void *res = (void *) realloc (ptr, size); + if (!res) + _libga68_abort ("Virtual memory exhausted\n"); + return res; +} + #if LIBGA68_WITH_GC #include diff --git a/libga68/ga68-posix.c b/libga68/ga68-posix.c index b6fba202497..221fb1a19fe 100644 --- a/libga68/ga68-posix.c +++ b/libga68/ga68-posix.c @@ -57,13 +57,14 @@ void _libga68_posixperror (uint32_t *s, size_t len, size_t stride) { size_t u8len; - uint8_t *u8str = _libga68_u32_to_u8 (s, len, stride, NULL, &u8len); + char *u8str = _libga68_u32_to_u8 (s, len, stride, &u8len); const char *errstr = strerror (_libga68_errno); (void) write (2, u8str, u8len); (void) write (2, ": ", 2); (void) write (2, errstr, strlen (errstr)); (void) write (2, "\n", 1); + _libga68_free_internal (u8str); } uint32_t * @@ -95,11 +96,7 @@ _libga68_posixfopen (const uint32_t *pathname, size_t len, size_t stride, int fd; int openflags = 0; size_t u8len; - const uint8_t *u8pathname = _libga68_u32_to_u8 (pathname, len, stride, NULL, - &u8len); - char *filepath = (char *) _libga68_malloc_internal (u8len + 1); - memcpy (filepath, u8pathname, u8len); - filepath[u8len] = '\0'; + char *filepath = _libga68_u32_to_u8 (pathname, len, stride, &u8len); /* Default mode: try read-write initially. If that fails, then try read-only. @@ -141,11 +138,11 @@ _libga68_posixcreat (uint32_t *pathname, size_t len, size_t stride, uint32_t mode) { size_t u8len; - uint8_t *u8pathname = _libga68_u32_to_u8 (pathname, len, stride, NULL, &u8len); - u8pathname[u8len] = '\0'; + char *filepath = _libga68_u32_to_u8 (pathname, len, stride, &u8len); - int res = creat (u8pathname, mode); + int res = creat (filepath, mode); _libga68_errno = errno; + _libga68_free_internal (filepath); return res; } @@ -189,14 +186,11 @@ void _libga68_posixgetenv (uint32_t *s, size_t len, size_t stride, uint32_t **r, size_t *rlen) { - size_t varlen; - char *varname = _libga68_u32_to_u8 (s, len, stride, NULL, &varlen); + size_t u8len; + char *varname = _libga68_u32_to_u8 (s, len, stride, &u8len); - char *var = _libga68_malloc_internal (varlen + 1); - memcpy (var, varname, varlen); - var[varlen] = '\0'; - char *val = getenv (var); - _libga68_free_internal (var); + char *val = getenv (varname); + _libga68_free_internal (varname); if (val == NULL) { @@ -222,10 +216,11 @@ int _libga68_posixfputs (int fd, uint32_t *s, size_t len, size_t stride) { size_t u8len; - uint8_t *u8str = _libga68_u32_to_u8 (s, len, stride, NULL, &u8len); + char *u8str = _libga68_u32_to_u8 (s, len, stride, &u8len); ssize_t ret = write (fd, u8str, u8len); _libga68_errno = errno; + _libga68_free_internal (u8str); if (ret == -1) return 0; else @@ -371,7 +366,7 @@ _libga68_posixfconnect (uint32_t *str, size_t len, size_t stride, int port) { size_t u8len; - uint8_t *u8host = _libga68_u32_to_u8 (str, len, stride, NULL, &u8len); + char *host = _libga68_u32_to_u8 (str, len, stride, &u8len); /* Create a stream socket. */ int fd = socket (AF_INET, SOCK_STREAM, 0); @@ -380,9 +375,6 @@ _libga68_posixfconnect (uint32_t *str, size_t len, size_t stride, goto error; /* Lookup the specified host. */ - char *host = _libga68_malloc_internal (u8len + 1); - memcpy (host, u8host, u8len); - host[u8len] = '\0'; struct hostent *server = gethostbyname (host); if (server == NULL) { @@ -409,8 +401,8 @@ _libga68_posixfconnect (uint32_t *str, size_t len, size_t stride, close_fd_and_error: close (fd); - error: _libga68_free_internal (host); + error: return -1; } diff --git a/libga68/ga68-unistr.c b/libga68/ga68-unistr.c index 2a71313c181..e37bd8c852d 100644 --- a/libga68/ga68-unistr.c +++ b/libga68/ga68-unistr.c @@ -305,34 +305,26 @@ _libga68_u8_uctomb (uint8_t *s, uint32_t uc, ptrdiff_t n) return -2; } -/* Convert UCS-4 to UTF-8 */ - -uint8_t * -_libga68_u32_to_u8 (const uint32_t *s, size_t n, size_t stride, - uint8_t *resultbuf, size_t *lengthp) +/* Convert S of size N with stride STRIDE UCS-4 to UTF-8. + Returns a pointer to the converted string with a traiiling '\0'. + The string length, not counting the trailling '\0', is returned on LENGTHP. + Returns NULL on error. + Callers *must* call _libga68_free_internal on a non-null result. */ + +char * +_libga68_u32_to_u8 (const uint32_t *s, size_t n, size_t stride, size_t *lengthp) { const uint32_t *s_end; /* Output string accumulator. */ - uint8_t *result; - size_t allocated; - size_t length; + uint8_t *result = NULL; + size_t allocated = 0; + size_t length = 0; stride = stride / sizeof (uint32_t); s_end = s + (n * stride); - if (resultbuf != NULL) - { - result = resultbuf; - allocated = *lengthp; - } - else - { - result = NULL; - allocated = 0; - } - length = 0; /* Invariants: - result is either == resultbuf or == NULL or malloc-allocated. + result is either == NULL or allocated by the internal malloc. If length > 0, then result != NULL. */ while (s < s_end) @@ -350,8 +342,8 @@ _libga68_u32_to_u8 (const uint32_t *s, size_t n, size_t stride, count = _libga68_u8_uctomb (result + length, uc, allocated - length); if (count == -1) { - if (!(result == resultbuf || result == NULL)) - free (result); + if (result != NULL) + _libga68_free_internal (result); errno = EILSEQ; return NULL; } @@ -362,15 +354,12 @@ _libga68_u32_to_u8 (const uint32_t *s, size_t n, size_t stride, allocated = (allocated > 0 ? 2 * allocated : 12); if (length + 6 > allocated) allocated = length + 6; - if (result == resultbuf || result == NULL) - memory = (uint8_t *) _libga68_malloc_leaf (allocated * sizeof (uint8_t)); + if (result == NULL) + memory = (uint8_t *) _libga68_malloc_internal (allocated * sizeof (uint8_t)); else memory = - (uint8_t *) _libga68_realloc (result, allocated * sizeof (uint8_t)); + (uint8_t *) _libga68_realloc_internal (result, allocated * sizeof (uint8_t)); - if (result == resultbuf && length > 0) - memcpy ((char *) memory, (char *) result, - length * sizeof (uint8_t)); result = memory; count = _libga68_u8_uctomb (result + length, uc, allocated - length); if (count < 0) @@ -384,26 +373,26 @@ _libga68_u32_to_u8 (const uint32_t *s, size_t n, size_t stride, if (result == NULL) { /* Return a non-NULL value. NULL means error. */ - result = (uint8_t *) _libga68_malloc_leaf (1); - if (result == NULL) - { - errno = ENOMEM; - return NULL; - } + result = (uint8_t *) _libga68_malloc_internal (1); } } - else if (result != resultbuf && length < allocated) + else { - /* Shrink the allocated memory if possible. */ - uint8_t *memory; - - memory = (uint8_t *) _libga68_realloc_unchecked (result, length * sizeof (uint8_t)); - if (memory != NULL) - result = memory; + if (length + 1 != allocated) + { + /* Resize the allocated memory to fit the string plus the trailling NULL. */ + uint8_t *memory; + + memory = + (uint8_t *) _libga68_realloc_internal (result, + (length +1) * sizeof (uint8_t)); + result = memory; + } + result[length] = 0x0; } *lengthp = length; - return result; + return (char *) result; } /* Used by ga68_u8_to_u32 below. */ diff --git a/libga68/ga68.h b/libga68/ga68.h index 8d1cf20c162..316a9e318d5 100644 --- a/libga68/ga68.h +++ b/libga68/ga68.h @@ -73,6 +73,7 @@ void *_libga68_malloc (size_t size); void *_libga68_malloc_leaf (size_t size); void *_libga68_malloc_internal (size_t size) GA68_HIDDEN; void *_libga68_realloc (void *ptr, size_t size) GA68_HIDDEN; +void *_libga68_realloc_internal (void *ptr, size_t size) GA68_HIDDEN; void *_libga68_realloc_unchecked (void *ptr, size_t size) GA68_HIDDEN; void _libga68_free_internal (void *ptr) GA68_HIDDEN; @@ -117,8 +118,8 @@ int _libga68_u32_cmp2 (const uint32_t *s1, size_t n1, size_t stride1, const uint32_t *s2, size_t n2, size_t stride2); int _libga68_u8_uctomb (uint8_t *s, uint32_t uc, ptrdiff_t n) GA68_HIDDEN; int _libga68_u8_mbtouc (uint32_t *puc, const uint8_t *s, size_t n) GA68_HIDDEN; -uint8_t *_libga68_u32_to_u8 (const uint32_t *s, size_t n, size_t stride, - uint8_t *resultbuf, size_t *lengthp) GA68_HIDDEN; +char *_libga68_u32_to_u8 (const uint32_t *s, size_t n, size_t stride, + size_t *lengthp) GA68_HIDDEN; uint32_t *_libga68_u8_to_u32 (const uint8_t *s, size_t n, uint32_t *resultbuf, size_t *lengthp);