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