Revision: 69045
          http://sourceforge.net/p/brlcad/code/69045
Author:   starseeker
Date:     2016-10-13 14:05:01 +0000 (Thu, 13 Oct 2016)
Log Message:
-----------
Victor found a problem with attr show.  There was unsigned math going on in the 
tab calculations for displaying selected attributes, and a long attribute value 
length resulted in an attempt to assign a negative value to the unsigned tab 
length.  The result was the vls logic trying work with the resulting garbage 
value and effectively hanging (may not technically have been an infinite loop, 
but looks that way to a user and it will eventually wipe out in some other way 
if it ever did move on.)  Rather than do all the special case foo, teach 
attr_print to handle either printing everything or printing an argv list of 
attributes.  Consolidates the logic and eliminates the problem case.

Modified Paths:
--------------
    brlcad/trunk/NEWS
    brlcad/trunk/src/libged/attr.c

Modified: brlcad/trunk/NEWS
===================================================================
--- brlcad/trunk/NEWS   2016-10-13 13:46:09 UTC (rev 69044)
+++ brlcad/trunk/NEWS   2016-10-13 14:05:01 UTC (rev 69045)
@@ -13,6 +13,7 @@
 --- 2016-07-XX  Release 7.26.2                                     ---
 ----------------------------------------------------------------------
 
+* fixed attr show error printing large attribute values - Cliff Yapp
 * fixed rt support for lights created prior to rel 6.0 - Sean Morrison
 * fixed infinite loop bug in when using shadow lights - Sean Morrison
 * removed man pages: erase_all, export_body, vrmgr, dall - Cliff Yapp

Modified: brlcad/trunk/src/libged/attr.c
===================================================================
--- brlcad/trunk/src/libged/attr.c      2016-10-13 13:46:09 UTC (rev 69044)
+++ brlcad/trunk/src/libged/attr.c      2016-10-13 14:05:01 UTC (rev 69045)
@@ -143,24 +143,51 @@
        return ATTR_UNKNOWN;
 }
 
-
 HIDDEN void
-attr_print(struct ged *gedp, struct bu_attribute_value_set *avs,
-          const size_t max_attr_name_len)
+attr_print(struct ged *gedp, struct bu_attribute_value_set *avs, int argc, 
const char **argv)
 {
+    size_t max_attr_name_len  = 0;
     struct bu_attribute_value_pair *avpp;
-    size_t i;
-
-    for (i = 0, avpp = avs->avp; i < avs->count; i++, avpp++) {
-       size_t len_diff = 0;
-       size_t count = 0;
-       bu_vls_printf(gedp->ged_result_str, "\t%s", avpp->name);
-       len_diff = max_attr_name_len - strlen(avpp->name);
-       while (count < (len_diff) + 1) {
-           bu_vls_printf(gedp->ged_result_str, " ");
-           count++;
+    size_t i, j;
+    /* If we don't have a specified set, do everything */
+    /* find the max_attr_name_len  */
+    if (argc == 0 || !argv) {
+       for (j = 0, avpp = avs->avp; j < avs->count; j++, avpp++) {
+           size_t len = strlen(avpp->name);
+           if (len > max_attr_name_len) max_attr_name_len = len;
        }
-       bu_vls_printf(gedp->ged_result_str, "%s\n", avpp->value);
+       for (i = 0, avpp = avs->avp; i < avs->count; i++, avpp++) {
+           size_t len_diff = 0;
+           size_t count = 0;
+           bu_vls_printf(gedp->ged_result_str, "\t%s", avpp->name);
+           len_diff = max_attr_name_len - strlen(avpp->name);
+           while (count < (len_diff) + 1) {
+               bu_vls_printf(gedp->ged_result_str, " ");
+               count++;
+           }
+           bu_vls_printf(gedp->ged_result_str, "%s\n", avpp->value);
+       }
+    } else {
+       for (i = 0; i < (size_t)argc; i++) {
+           size_t len = strlen(argv[i]);
+           if (len > max_attr_name_len) max_attr_name_len = len;
+       }
+       for (i = 0; i < (size_t)argc; i++) {
+           const char *aval = bu_avs_get(avs, argv[i]);
+           size_t len_diff = 0;
+           size_t count = 0;
+           if (!aval) {
+               bu_vls_sprintf(gedp->ged_result_str, "ERROR: attribute %s not 
found\n", argv[i]);
+               return;
+           }
+           bu_vls_printf(gedp->ged_result_str, "\t%s", argv[i]);
+           len_diff = max_attr_name_len - strlen(argv[i]);
+           while (count < (len_diff) + 1) {
+               bu_vls_printf(gedp->ged_result_str, " ");
+               count++;
+           }
+           bu_vls_printf(gedp->ged_result_str, "%s\n", aval);
+       }
     }
 }
 
@@ -239,7 +266,6 @@
        for (i = 0; i < path_cnt; i++) {
            /* for pretty printing */
            size_t j = 0;
-           size_t max_attr_name_len  = 0;
            size_t max_attr_value_len = 0;
 
            struct bu_attribute_value_set avs;
@@ -254,11 +280,8 @@
            bu_sort(&avs.avp[0], avs.count, sizeof(struct 
bu_attribute_value_pair), attr_cmp, NULL);
            /* get a jump on calculating name and value lengths */
            for (j = 0, avpp = avs.avp; j < avs.count; j++, avpp++) {
-               size_t len = strlen(avpp->name);
-               if (len > max_attr_name_len)
-                   max_attr_name_len = len;
                if (avpp->value) {
-                   len = strlen(avpp->value);
+                   size_t len = strlen(avpp->value);
                    if (len > max_attr_value_len)
                        max_attr_value_len = len;
                }
@@ -270,7 +293,7 @@
            }
            if (argc == 3) {
                /* just list the already sorted attribute-value pairs */
-               attr_print(gedp, &avs, max_attr_name_len);
+               attr_print(gedp, &avs, 0, NULL);
            } else {
                /* argv[3] is the sort type: 'case', 'nocase', 'value', 
'value-nocase' */
                if (BU_STR_EQUIV(argv[3], NOCASE)) {
@@ -283,7 +306,7 @@
                    ; /* don't need to do anything since this is the existing 
(default) sort */
                }
                /* just list the already sorted attribute-value pairs */
-               attr_print(gedp, &avs, max_attr_name_len);
+               attr_print(gedp, &avs, 0, NULL);
            }
            bu_avs_free(&avs);
        }
@@ -540,11 +563,9 @@
     } else if (scmd == ATTR_SHOW) {
        for (i = 0; i < path_cnt; i++) {
            /* for pretty printing */
-           size_t max_attr_name_len  = 0;
            size_t max_attr_value_len = 0;
 
            size_t j = 0;
-           size_t tabs1 = 0;
            struct bu_attribute_value_set avs;
            bu_avs_init_empty(&avs);
            dp = paths[i];
@@ -556,11 +577,8 @@
 
            /* get a jump on calculating name and value lengths */
            for (j = 0, avpp = avs.avp; j < avs.count; j++, avpp++) {
-               size_t len = strlen(avpp->name);
-               if (len > max_attr_name_len)
-                   max_attr_name_len = len;
                if (avpp->value) {
-                   len = strlen(avpp->value);
+                   size_t len = strlen(avpp->value);
                    if (len > max_attr_value_len)
                        max_attr_value_len = len;
                }
@@ -573,54 +591,10 @@
 
            if (argc == 3) {
                /* just display all attributes */
-               attr_print(gedp, &avs, max_attr_name_len);
+               attr_print(gedp, &avs, 0, NULL);
            } else {
-               const char *val;
-               size_t len;
-
                /* show just the specified attributes */
-               for (j = 0; j < (size_t)argc; j++) {
-                   len = strlen(argv[j]);
-                   if (len > max_attr_name_len) {
-                       max_attr_name_len = len;
-                   }
-               }
-               tabs1 = 2 + max_attr_name_len/8;
-               for (j = 3; j < (size_t)argc; j++) {
-                   size_t tabs2;
-                   size_t k;
-                   const char *c;
-
-                   val = bu_avs_get(&avs, argv[j]);
-                   if (!val && path_cnt == 1) {
-                       bu_vls_printf(gedp->ged_result_str,
-                               "Object %s does not have a %s attribute\n",
-                               dp->d_namep,
-                               argv[j]);
-                       bu_avs_free(&avs);
-                       return GED_ERROR;
-                   } else {
-                       if (val) {
-                           bu_vls_printf(gedp->ged_result_str, "\t%s", 
argv[j]);
-                           len = strlen(val);
-                           tabs2 = tabs1 - 1 - len/8;
-                           for (k = 0; k < tabs2; k++) {
-                               bu_vls_putc(gedp->ged_result_str, '\t');
-                           }
-                           c = val;
-                           while (*c) {
-                               bu_vls_putc(gedp->ged_result_str, *c);
-                               if (*c == '\n') {
-                                   for (k = 0; k < tabs1; k++) {
-                                       bu_vls_putc(gedp->ged_result_str, '\t');
-                                   }
-                               }
-                               c++;
-                           }
-                           bu_vls_putc(gedp->ged_result_str, '\n');
-                       }
-                   }
-               }
+               attr_print(gedp, &avs, argc - 3, argv + 3);
            }
        }
     } else {

This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most 
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
_______________________________________________
BRL-CAD Source Commits mailing list
brlcad-commits@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/brlcad-commits

Reply via email to