Rather than use strtok_r using an input "path" variable which may or may not be NULL and thus alter the results, use the virStringSplitCount API in order to parse the path. Found by Coverity Signed-off-by: John Ferlan <jferlan@xxxxxxxxxx> --- src/esx/esx_vi.c | 61 ++++++++++++++++++++++++-------------------------------- 1 file changed, 26 insertions(+), 35 deletions(-) diff --git a/src/esx/esx_vi.c b/src/esx/esx_vi.c index a28ac7b..f151dc4 100644 --- a/src/esx/esx_vi.c +++ b/src/esx/esx_vi.c @@ -1179,22 +1179,17 @@ esxVI_Context_LookupManagedObjects(esxVI_Context *ctx) int esxVI_Context_LookupManagedObjectsByPath(esxVI_Context *ctx, const char *path) { + char **tmp = NULL; + size_t idx, ntmp = 0; int result = -1; - char *tmp = NULL; - char *saveptr = NULL; - char *previousItem = NULL; - char *item = NULL; virBuffer buffer = VIR_BUFFER_INITIALIZER; esxVI_ManagedObjectReference *root = NULL; esxVI_Folder *folder = NULL; - if (VIR_STRDUP(tmp, path) < 0) + if (!(tmp = virStringSplitCount(path, "/", 0, &ntmp))) goto cleanup; - /* Lookup Datacenter */ - item = strtok_r(tmp, "/", &saveptr); - - if (!item) { + if (ntmp == 0) { virReportError(VIR_ERR_INVALID_ARG, _("Path '%s' does not specify a datacenter"), path); goto cleanup; @@ -1202,11 +1197,12 @@ esxVI_Context_LookupManagedObjectsByPath(esxVI_Context *ctx, const char *path) root = ctx->service->rootFolder; - while (!ctx->datacenter && item) { + for (idx = 0; idx < ntmp && !ctx->datacenter; ++idx) { + esxVI_Folder_Free(&folder); - /* Try to lookup item as a folder */ - if (esxVI_LookupFolder(ctx, item, root, NULL, &folder, + /* Try to lookup entry as a folder */ + if (esxVI_LookupFolder(ctx, tmp[idx], root, NULL, &folder, esxVI_Occurrence_OptionalItem) < 0) { goto cleanup; } @@ -1219,8 +1215,9 @@ esxVI_Context_LookupManagedObjectsByPath(esxVI_Context *ctx, const char *path) root = folder->_reference; folder->_reference = NULL; } else { - /* Try to lookup item as a datacenter */ - if (esxVI_LookupDatacenter(ctx, item, root, NULL, &ctx->datacenter, + /* Try to lookup entry as a datacenter */ + if (esxVI_LookupDatacenter(ctx, tmp[idx], root, NULL, + &ctx->datacenter, esxVI_Occurrence_OptionalItem) < 0) { goto cleanup; } @@ -1230,10 +1227,7 @@ esxVI_Context_LookupManagedObjectsByPath(esxVI_Context *ctx, const char *path) if (virBufferUse(&buffer) > 0) virBufferAddChar(&buffer, '/'); - virBufferAdd(&buffer, item, -1); - - previousItem = item; - item = strtok_r(NULL, "/", &saveptr); + virBufferAdd(&buffer, tmp[idx], -1); } if (!ctx->datacenter) { @@ -1248,9 +1242,10 @@ esxVI_Context_LookupManagedObjectsByPath(esxVI_Context *ctx, const char *path) ctx->datacenterPath = virBufferContentAndReset(&buffer); /* Lookup (Cluster)ComputeResource */ - if (!item) { + if (!tmp[idx]) { virReportError(VIR_ERR_INVALID_ARG, - _("Path '%s' does not specify a compute resource"), path); + _("Path '%s' does not specify a compute resource"), + path); goto cleanup; } @@ -1259,11 +1254,11 @@ esxVI_Context_LookupManagedObjectsByPath(esxVI_Context *ctx, const char *path) root = ctx->datacenter->hostFolder; - while (!ctx->computeResource && item) { + for (; idx < ntmp && !ctx->computeResource; ++idx) { esxVI_Folder_Free(&folder); - /* Try to lookup item as a folder */ - if (esxVI_LookupFolder(ctx, item, root, NULL, &folder, + /* Try to lookup entry as a folder */ + if (esxVI_LookupFolder(ctx, tmp[idx], root, NULL, &folder, esxVI_Occurrence_OptionalItem) < 0) { goto cleanup; } @@ -1276,8 +1271,8 @@ esxVI_Context_LookupManagedObjectsByPath(esxVI_Context *ctx, const char *path) root = folder->_reference; folder->_reference = NULL; } else { - /* Try to lookup item as a compute resource */ - if (esxVI_LookupComputeResource(ctx, item, root, NULL, + /* Try to lookup entry as a compute resource */ + if (esxVI_LookupComputeResource(ctx, tmp[idx], root, NULL, &ctx->computeResource, esxVI_Occurrence_OptionalItem) < 0) { goto cleanup; @@ -1288,10 +1283,7 @@ esxVI_Context_LookupManagedObjectsByPath(esxVI_Context *ctx, const char *path) if (virBufferUse(&buffer) > 0) virBufferAddChar(&buffer, '/'); - virBufferAdd(&buffer, item, -1); - - previousItem = item; - item = strtok_r(NULL, "/", &saveptr); + virBufferAdd(&buffer, tmp[idx], -1); } if (!ctx->computeResource) { @@ -1315,24 +1307,23 @@ esxVI_Context_LookupManagedObjectsByPath(esxVI_Context *ctx, const char *path) /* Lookup HostSystem */ if (STREQ(ctx->computeResource->_reference->type, "ClusterComputeResource")) { - if (!item) { + if (!tmp[idx]) { virReportError(VIR_ERR_INVALID_ARG, _("Path '%s' does not specify a host system"), path); goto cleanup; } /* The path specified a cluster, it has to specify a host system too */ - previousItem = item; - item = strtok_r(NULL, "/", &saveptr); + idx++; } - if (item) { + if (tmp[idx]) { virReportError(VIR_ERR_INVALID_ARG, _("Path '%s' ends with an excess item"), path); goto cleanup; } - if (VIR_STRDUP(ctx->hostSystemName, previousItem) < 0) + if (VIR_STRDUP(ctx->hostSystemName, tmp[idx - 1]) < 0) goto cleanup; if (esxVI_LookupHostSystem(ctx, ctx->hostSystemName, @@ -1359,7 +1350,7 @@ esxVI_Context_LookupManagedObjectsByPath(esxVI_Context *ctx, const char *path) esxVI_ManagedObjectReference_Free(&root); } - VIR_FREE(tmp); + virStringFreeListCount(tmp, ntmp); esxVI_Folder_Free(&folder); return result; -- 2.5.5 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list