Commit 171e0170c262f0e769f6615052ac81959a2cdca4

Pierre Le Marre 2023-10-25T20:39:39

Fix memory leak in FindFileInXkbPath The string `buf` was not freed after each call to `asprintf_safe`. Avoid allocating and introduce the new message: `XKB_ERROR_INSUFFICIENT_BUFFER_SIZE`.

diff --git a/doc/message-registry.md b/doc/message-registry.md
index 24b2ffc..b5358f0 100644
--- a/doc/message-registry.md
+++ b/doc/message-registry.md
@@ -6,7 +6,7 @@ NOTE: This file has been generated automatically by “update-message-registry.p
 -->
 
 This page lists the warnings and errors generated by xkbcommon.
-There are currently 53 entries.
+There are currently 54 entries.
 
 @todo The documentation of the log messages is a work in progress.
 
@@ -21,6 +21,7 @@ There are currently 53 entries.
 | [XKB-101] | `illegal-keycode-alias` | Illegal keycode alias with the name of a real key | Warning |
 | [XKB-107] | `unrecognized-keysym` | Warn on unrecognized keysyms | Warning |
 | [XKB-123] | `undeclared-virtual-modifier` | A virtual modifier is used before being declared | Error |
+| [XKB-134] | `insufficient-buffer-size` | A buffer has an insufficient size | Error |
 | [XKB-150] | `wrong-statement-type` | The type of the statement is not allowed in the context | Error |
 | [XKB-172] | `unsupported-geometry-section` | Geometry sections are not supported | Warning |
 | [XKB-183] | `cannot-infer-key-type` | Warn if no key type can be inferred | Warning |
@@ -175,6 +176,14 @@ key <AB08> {[ comma, semicolon, periodcentered, multiply ]};
   <dt>Summary</dt><dd>A virtual modifier is used before being declared</dd>
 </dl>
 
+### XKB-134 – Insufficient buffer size {#XKB-134}
+
+<dl>
+  <dt>Since</dt><dd>1.0.0</dd>
+  <dt>Type</dt><dd>Error</dd>
+  <dt>Summary</dt><dd>A buffer has an insufficient size</dd>
+</dl>
+
 ### XKB-150 – Wrong statement type {#XKB-150}
 
 <dl>
@@ -630,6 +639,7 @@ The modifiers used in `map` or `preserve` entries should be declared using the e
 [XKB-101]: @ref XKB-101
 [XKB-107]: @ref XKB-107
 [XKB-123]: @ref XKB-123
+[XKB-134]: @ref XKB-134
 [XKB-150]: @ref XKB-150
 [XKB-172]: @ref XKB-172
 [XKB-183]: @ref XKB-183
diff --git a/doc/message-registry.yaml b/doc/message-registry.yaml
index 9f4c450..0b7db81 100644
--- a/doc/message-registry.yaml
+++ b/doc/message-registry.yaml
@@ -8,7 +8,7 @@
 # • Codes must be in the range 1..999. This range may be extended once every
 #   code has be assigned.
 #
-# See the following guidelines for futher details on good practices:
+# See the following guidelines for further details on good practices:
 # https://github.com/haskellfoundation/error-message-index/blob/main/tool-developers.md#code-assignment-recommendations
 
 # NOTE: Field “added: ALWAYS” means that the precise version is unknown and
@@ -85,6 +85,11 @@
   added: ALWAYS
   type: error
   description: "A virtual modifier is used before being declared"
+- id: "insufficient-buffer-size"
+  code: 134
+  added: ALWAYS
+  type: error
+  description: "A buffer has an insufficient size"
 - id: "wrong-statement-type"
   code: 150
   added: ALWAYS
diff --git a/src/messages-codes.h b/src/messages-codes.h
index af7bb93..3206831 100644
--- a/src/messages-codes.h
+++ b/src/messages-codes.h
@@ -30,6 +30,8 @@ enum xkb_message_code {
     XKB_WARNING_UNRECOGNIZED_KEYSYM = 107,
     /** A virtual modifier is used before being declared */
     XKB_ERROR_UNDECLARED_VIRTUAL_MODIFIER = 123,
+    /** A buffer has an insufficient size */
+    XKB_ERROR_INSUFFICIENT_BUFFER_SIZE = 134,
     /** The type of the statement is not allowed in the context */
     XKB_ERROR_WRONG_STATEMENT_TYPE = 150,
     /** Geometry sections are not supported */
diff --git a/src/xkbcomp/include.c b/src/xkbcomp/include.c
index d47156e..1fa2153 100644
--- a/src/xkbcomp/include.c
+++ b/src/xkbcomp/include.c
@@ -247,28 +247,27 @@ FindFileInXkbPath(struct xkb_context *ctx, const char *name,
 {
     unsigned int i;
     FILE *file = NULL;
-    char *buf = NULL;
+    char buf[PATH_MAX];
     const char *typeDir;
 
     typeDir = DirectoryForInclude(type);
 
     for (i = *offset; i < xkb_context_num_include_paths(ctx); i++) {
-        buf = asprintf_safe("%s/%s/%s", xkb_context_include_path_get(ctx, i),
-                            typeDir, name);
-        if (!buf) {
+        if (!snprintf_safe(buf, sizeof(buf), "%s/%s/%s",
+                           xkb_context_include_path_get(ctx, i),
+                           typeDir, name)) {
             log_err(ctx,
-                    XKB_ERROR_ALLOCATION_ERROR,
-                    "Failed to alloc buffer for (%s/%s/%s)\n",
+                    XKB_ERROR_INSUFFICIENT_BUFFER_SIZE,
+                    "Path is too long: expected max length of %lu, got: %s/%s/%s\n",
+                    (unsigned long int) sizeof(buf),
                     xkb_context_include_path_get(ctx, i), typeDir, name);
             continue;
         }
 
         file = fopen(buf, "rb");
         if (file) {
-            if (pathRtrn) {
-                *pathRtrn = buf;
-                buf = NULL;
-            }
+            if (pathRtrn)
+                *pathRtrn = strdup(buf);
             *offset = i;
             goto out;
         }
@@ -284,7 +283,6 @@ FindFileInXkbPath(struct xkb_context *ctx, const char *name,
     }
 
 out:
-    free(buf);
     return file;
 }
 
diff --git a/tools/messages.c b/tools/messages.c
index 9230dfd..a0ffd95 100644
--- a/tools/messages.c
+++ b/tools/messages.c
@@ -45,6 +45,7 @@ static const struct xkb_message_entry xkb_messages[] = {
     {XKB_WARNING_ILLEGAL_KEYCODE_ALIAS, "Illegal keycode alias"},
     {XKB_WARNING_UNRECOGNIZED_KEYSYM, "Unrecognized keysym"},
     {XKB_ERROR_UNDECLARED_VIRTUAL_MODIFIER, "Undeclared virtual modifier"},
+    {XKB_ERROR_INSUFFICIENT_BUFFER_SIZE, "Insufficient buffer size"},
     {XKB_ERROR_WRONG_STATEMENT_TYPE, "Wrong statement type"},
     {XKB_WARNING_UNSUPPORTED_GEOMETRY_SECTION, "Unsupported geometry section"},
     {XKB_WARNING_CANNOT_INFER_KEY_TYPE, "Cannot infer key type"},