I have product class machine names that are longer than 32 characters, there was no error check that prevented me from creating these product class machine names. When I try to view a product created from this class, I get no images, no comments and no node options because the variable was created using the full string, not the truncated pcid string. The catalog also does not display the product images.

I see 2 ways to fix this, either change the size of pcid in the table uc_product_classes from 32 to 64 or truncate the value of the pcid variable to 32 characters prior to creating any variables in the variable table with it. Either way there should be an error check on the size of the string.

Here is the code where the bug is. The actual bug is caused during the INSERT sql statement.

/**
 * Form submission handler for uc_product_class_form().
 *
 * @see uc_product_class_form()
 * @see uc_product_class_form_validate()
 */
function uc_product_class_form_submit($form, &$form_state) {
  $is_new = $form['pcid']['#type'] == 'textfield';

  $pcid = $form_state['values']['pcid'];

  if ($is_new) {
    // Convert whitespace to underscores, and remove other non-alphanumeric characters.
    $pcid = preg_replace(array('/\s+/', '/\W/'), array('_', ''), strtolower($pcid));

    db_query("INSERT INTO {uc_product_classes} (pcid, name, description) VALUES ('%s', '%s', '%s')", $pcid, $form_state['values']['name'], $form_state['values']['description']);
    uc_product_node_info(TRUE);
    variable_set('node_options_'. $pcid, variable_get('node_options_product', array('status', 'promote')));

    if (module_exists('comment')) {
      variable_set('comment_'. $pcid, variable_get('comment_product', COMMENT_NODE_READ_WRITE));
    }

    module_invoke_all('product_class', $pcid, 'insert');
  }
  else {
    db_query("UPDATE {uc_product_classes} SET name = '%s', description = '%s' WHERE pcid = '%s'", $form_state['values']['name'], $form_state['values']['description'], $pcid);
    db_query("UPDATE {node_type} SET name = '%s', description = '%s' WHERE type = '%s'", $form_state['values']['name'], $form_state['values']['description'], $pcid);
    uc_product_node_info(TRUE);

    module_invoke_all('product_class', $pcid, 'update');
  }

  node_types_rebuild();
  if ($is_new && module_exists('imagefield')) {
    uc_product_add_default_image_field($pcid);
  }
  menu_rebuild();

  drupal_set_message(t('Product class saved.'));
}

Comments

longwave’s picture

Priority: Major » Normal
Status: Active » Fixed

Fix committed to both branches: http://drupalcode.org/project/ubercart.git/commitdiff/ca62043

The class ID field was meant to be limited to 32 characters, but a single character typo meant this limit wasn't actually enforced.

longwave’s picture

Note that we cannot allow product class names longer than 32 characters, as Drupal does not allow content type machine names to be longer than that.

pcher1bw’s picture

Based on the speed with which you patched this, I'm going to assume that my bug report was pretty clear.

I understand your reasoning and I will have to go back and recreate all the product classes with shorter names.

longwave’s picture

Yes, I forgot to thank you for the detailed bug report, sorry!

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.