Print this page
8954 libtopo cannot handle any array type other than string_array.
Reviewed by: Andy Stormont astormont@racktopsystems.com
Reviewed by: David Höppner 0xffea@gmail.com
Reviewed by: Rob Johnston rob.johnston@joyent.com

Split Close
Expand all
Collapse all
          --- old/usr/src/lib/fm/topo/libtopo/common/topo_xml.c
          +++ new/usr/src/lib/fm/topo/libtopo/common/topo_xml.c
↓ open down ↓ 14 lines elided ↑ open up ↑
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  
  22   22  /*
  23   23   * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
  24   24   * Copyright (c) 2013, Joyent, Inc. All rights reserved.
       25 + * Copyright (c) 2018, Western Digital Technologies, Inc. All rights reserved.
  25   26   */
  26   27  
  27   28  #include <libxml/parser.h>
  28   29  #include <libxml/xinclude.h>
  29   30  #include <sys/fm/protocol.h>
  30   31  #include <assert.h>
  31   32  #include <string.h>
  32   33  #include <strings.h>
  33   34  #include <ctype.h>
  34   35  #include <errno.h>
↓ open down ↓ 152 lines elided ↑ open up ↑
 187  188                  (void) topo_mod_seterrno(mp, ETOPO_PRSR_BADTYPE);
 188  189                  xmlFree(str);
 189  190                  return (TOPO_TYPE_INVALID);
 190  191          }
 191  192          xmlFree(str);
 192  193          return (rv);
 193  194  }
 194  195  
 195  196  static int
 196  197  xlate_common(topo_mod_t *mp, xmlNodePtr xn, topo_type_t ptype, nvlist_t *nvl,
 197      -const char *name)
      198 +    const char *name)
 198  199  {
 199  200          int rv;
 200  201          uint64_t ui;
 201  202          uint_t i = 0, nelems = 0;
 202  203          nvlist_t *fmri;
 203  204          xmlChar *str;
 204  205          char **strarrbuf;
 205  206          void *arrbuf;
 206  207          nvlist_t **nvlarrbuf;
 207  208          xmlNodePtr cn;
↓ open down ↓ 29 lines elided ↑ open up ↑
 237  238          case TOPO_TYPE_STRING:
 238  239                  if ((str = xmlGetProp(xn, (xmlChar *)Value)) == NULL)
 239  240                          return (-1);
 240  241                  rv = nvlist_add_string(nvl, name, (char *)str);
 241  242                  xmlFree(str);
 242  243                  break;
 243  244          case TOPO_TYPE_INT32_ARRAY:
 244  245          case TOPO_TYPE_UINT32_ARRAY:
 245  246          case TOPO_TYPE_INT64_ARRAY:
 246  247          case TOPO_TYPE_UINT64_ARRAY:
 247      -                for (cn = xn->xmlChildrenNode; cn != NULL; cn = cn->next)
 248      -                        if ((xmlStrcmp(cn->name, (xmlChar *)Propitem) == 0) ||
 249      -                            (xmlStrcmp(cn->name, (xmlChar *)Argitem) == 0))
 250      -                                nelems++;
 251      -
 252      -                if (nelems < 1) {
 253      -                        topo_dprintf(mp->tm_hdl, TOPO_DBG_ERR, "No <propitem> "
 254      -                            "or <argitem> elements found for array val");
 255      -                        return (-1);
 256      -                }
 257      -                if ((arrbuf = topo_mod_alloc(mp, (nelems * sizeof (uint64_t))))
 258      -                    == NULL)
 259      -                        return (topo_mod_seterrno(mp, ETOPO_NOMEM));
 260      -                break;
 261  248          case TOPO_TYPE_STRING_ARRAY:
      249 +        case TOPO_TYPE_FMRI_ARRAY:
 262  250                  for (cn = xn->xmlChildrenNode; cn != NULL; cn = cn->next)
 263  251                          if ((xmlStrcmp(cn->name, (xmlChar *)Propitem) == 0) ||
 264  252                              (xmlStrcmp(cn->name, (xmlChar *)Argitem) == 0))
 265  253                                  nelems++;
 266  254  
 267  255                  if (nelems < 1) {
 268  256                          topo_dprintf(mp->tm_hdl, TOPO_DBG_ERR, "No <propitem> "
 269  257                              "or <argitem> elements found for array val");
 270  258                          return (-1);
 271  259                  }
 272      -                if ((strarrbuf = topo_mod_alloc(mp, (nelems * sizeof (char *))))
 273      -                    == NULL)
 274      -                        return (topo_mod_seterrno(mp, ETOPO_NOMEM));
 275  260                  break;
 276      -        case TOPO_TYPE_FMRI_ARRAY:
 277      -                for (cn = xn->xmlChildrenNode; cn != NULL; cn = cn->next)
 278      -                        if ((xmlStrcmp(cn->name, (xmlChar *)Propitem) == 0) ||
 279      -                            (xmlStrcmp(cn->name, (xmlChar *)Argitem) == 0))
 280      -                                nelems++;
 281      -
 282      -                if (nelems < 1) {
 283      -                        topo_dprintf(mp->tm_hdl, TOPO_DBG_ERR, "No <propitem> "
 284      -                            "elements found for array prop");
 285      -                        return (-1);
 286      -                }
 287      -                if ((nvlarrbuf = topo_mod_alloc(mp, (nelems *
 288      -                    sizeof (nvlist_t *)))) == NULL)
 289      -                        return (topo_mod_seterrno(mp, ETOPO_NOMEM));
 290      -                break;
 291  261          default:
 292  262                  topo_dprintf(mp->tm_hdl, TOPO_DBG_ERR,
 293  263                      "Unrecognized type attribute (ptype = %d)\n", ptype);
 294  264                  return (topo_mod_seterrno(mp, ETOPO_PRSR_BADTYPE));
 295  265          }
 296  266  
 297  267          switch (ptype) {
 298  268          case TOPO_TYPE_INT32_ARRAY:
      269 +                if ((arrbuf = topo_mod_alloc(mp, (nelems * sizeof (int32_t))))
      270 +                    == NULL)
      271 +                        return (topo_mod_seterrno(mp, ETOPO_NOMEM));
 299  272                  for (cn = xn->xmlChildrenNode; cn != NULL; cn = cn->next) {
 300  273                          if ((xmlStrcmp(cn->name, (xmlChar *)Propitem) == 0) ||
 301  274                              (xmlStrcmp(cn->name, (xmlChar *)Argitem) == 0)) {
 302  275  
 303      -                                if ((str = xmlGetProp(xn, (xmlChar *)Value))
      276 +                                if ((str = xmlGetProp(cn, (xmlChar *)Value))
 304  277                                      == NULL)
 305  278                                          return (-1);
 306  279  
 307  280                                  ((int32_t *)arrbuf)[i++]
 308  281                                      = atoi((const char *)str);
 309  282                                  xmlFree(str);
 310  283                          }
 311  284                  }
 312  285  
 313  286                  rv = nvlist_add_int32_array(nvl, name, (int32_t *)arrbuf,
 314  287                      nelems);
 315      -                free(arrbuf);
      288 +                topo_mod_free(mp, arrbuf, (nelems * sizeof (int32_t)));
 316  289                  break;
 317  290          case TOPO_TYPE_UINT32_ARRAY:
      291 +                if ((arrbuf = topo_mod_alloc(mp, (nelems * sizeof (uint32_t))))
      292 +                    == NULL)
      293 +                        return (topo_mod_seterrno(mp, ETOPO_NOMEM));
 318  294                  for (cn = xn->xmlChildrenNode; cn != NULL; cn = cn->next) {
 319  295                          if ((xmlStrcmp(cn->name, (xmlChar *)Propitem) == 0) ||
 320  296                              (xmlStrcmp(cn->name, (xmlChar *)Argitem) == 0)) {
 321  297  
 322      -                                if ((str = xmlGetProp(xn, (xmlChar *)Value))
      298 +                                if ((str = xmlGetProp(cn, (xmlChar *)Value))
 323  299                                      == NULL)
 324  300                                          return (-1);
 325  301  
 326  302                                  ((uint32_t *)arrbuf)[i++]
 327  303                                      = atoi((const char *)str);
 328  304                                  xmlFree(str);
 329  305                          }
 330  306                  }
 331  307  
 332  308                  rv = nvlist_add_uint32_array(nvl, name, (uint32_t *)arrbuf,
 333  309                      nelems);
 334      -                free(arrbuf);
      310 +                topo_mod_free(mp, arrbuf, (nelems * sizeof (uint32_t)));
 335  311                  break;
 336  312          case TOPO_TYPE_INT64_ARRAY:
      313 +                if ((arrbuf = topo_mod_alloc(mp, (nelems * sizeof (int64_t))))
      314 +                    == NULL)
      315 +                        return (topo_mod_seterrno(mp, ETOPO_NOMEM));
 337  316                  for (cn = xn->xmlChildrenNode; cn != NULL; cn = cn->next) {
 338  317                          if ((xmlStrcmp(cn->name, (xmlChar *)Propitem) == 0) ||
 339  318                              (xmlStrcmp(cn->name, (xmlChar *)Argitem) == 0)) {
 340  319  
 341      -                                if ((str = xmlGetProp(xn, (xmlChar *)Value))
      320 +                                if ((str = xmlGetProp(cn, (xmlChar *)Value))
 342  321                                      == NULL)
 343  322                                          return (-1);
 344  323  
 345  324                                  ((int64_t *)arrbuf)[i++]
 346  325                                      = atol((const char *)str);
 347  326                                  xmlFree(str);
 348  327                          }
 349  328                  }
 350  329  
 351  330                  rv = nvlist_add_int64_array(nvl, name, (int64_t *)arrbuf,
 352  331                      nelems);
 353      -                free(arrbuf);
      332 +                topo_mod_free(mp, arrbuf, (nelems * sizeof (int64_t)));
 354  333                  break;
 355  334          case TOPO_TYPE_UINT64_ARRAY:
      335 +                if ((arrbuf = topo_mod_alloc(mp, (nelems * sizeof (uint64_t))))
      336 +                    == NULL)
      337 +                        return (topo_mod_seterrno(mp, ETOPO_NOMEM));
 356  338                  for (cn = xn->xmlChildrenNode; cn != NULL; cn = cn->next) {
 357  339                          if ((xmlStrcmp(cn->name, (xmlChar *)Propitem) == 0) ||
 358  340                              (xmlStrcmp(cn->name, (xmlChar *)Argitem) == 0)) {
 359  341  
 360      -                                if ((str = xmlGetProp(xn, (xmlChar *)Value))
      342 +                                if ((str = xmlGetProp(cn, (xmlChar *)Value))
 361  343                                      == NULL)
 362  344                                          return (-1);
 363  345  
 364  346                                  ((uint64_t *)arrbuf)[i++]
 365  347                                      = atol((const char *)str);
 366  348                                  xmlFree(str);
 367  349                          }
 368  350                  }
 369  351  
 370  352                  rv = nvlist_add_uint64_array(nvl, name, arrbuf,
 371  353                      nelems);
 372      -                free(arrbuf);
      354 +                topo_mod_free(mp, arrbuf, (nelems * sizeof (uint64_t)));
 373  355                  break;
 374  356          case TOPO_TYPE_STRING_ARRAY:
      357 +                if ((strarrbuf = topo_mod_alloc(mp, (nelems * sizeof (char *))))
      358 +                    == NULL)
      359 +                        return (topo_mod_seterrno(mp, ETOPO_NOMEM));
 375  360                  for (cn = xn->xmlChildrenNode; cn != NULL; cn = cn->next) {
 376  361                          if ((xmlStrcmp(cn->name, (xmlChar *)Propitem) == 0) ||
 377  362                              (xmlStrcmp(cn->name, (xmlChar *)Argitem) == 0)) {
 378  363  
 379  364                                  if ((str = xmlGetProp(cn, (xmlChar *)Value))
 380  365                                      == NULL)
 381  366                                          return (-1);
 382  367  
 383  368                                  strarrbuf[i++] =
 384  369                                      topo_mod_strdup(mp, (const char *)str);
 385  370                                  xmlFree(str);
 386  371                          }
 387  372                  }
 388  373  
 389  374                  rv = nvlist_add_string_array(nvl, name, strarrbuf, nelems);
 390  375                  strarr_free(mp, strarrbuf, nelems);
 391  376                  break;
 392  377          case TOPO_TYPE_FMRI_ARRAY:
      378 +                if ((nvlarrbuf = topo_mod_alloc(mp, (nelems *
      379 +                    sizeof (nvlist_t *)))) == NULL)
      380 +                        return (topo_mod_seterrno(mp, ETOPO_NOMEM));
 393  381                  for (cn = xn->xmlChildrenNode; cn != NULL; cn = cn->next) {
 394  382                          if ((xmlStrcmp(cn->name, (xmlChar *)Propitem) == 0) ||
 395  383                              (xmlStrcmp(cn->name, (xmlChar *)Argitem) == 0)) {
 396  384  
 397      -                                if ((str = xmlGetProp(xn, (xmlChar *)Value))
      385 +                                if ((str = xmlGetProp(cn, (xmlChar *)Value))
 398  386                                      == NULL)
 399  387                                          return (-1);
 400  388  
 401  389                                  if (topo_mod_str2nvl(mp, (const char *)str,
 402  390                                      &(nvlarrbuf[i++])) < 0) {
 403  391                                          xmlFree(str);
 404  392                                          return (-1);
 405  393                                  }
 406  394                                  xmlFree(str);
 407  395                          }
 408  396                  }
 409  397  
 410  398                  rv = nvlist_add_nvlist_array(nvl, name, nvlarrbuf,
 411  399                      nelems);
 412      -                free(nvlarrbuf);
      400 +                topo_mod_free(mp, nvlarrbuf, (nelems * sizeof (nvlist_t *)));
 413  401                  break;
 414  402          }
 415  403  
 416  404          if (rv != 0) {
 417  405                  topo_dprintf(mp->tm_hdl, TOPO_DBG_ERR,
 418  406                      "Nvlist construction failed.\n");
 419  407                  return (topo_mod_seterrno(mp, ETOPO_NOMEM));
 420  408          } else
 421  409                  return (0);
 422  410  }
↓ open down ↓ 1713 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX