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(a)redhat.com>
---
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