$encode_header_key = '' if ( !$encode_header_key );
$hide_auth_header = 'false' if ( !$hide_auth_header );
$time_zone_type = '0' if ( !$time_zone_type );
+$prefs_user_size = 128 if ( !$prefs_user_size );
+$prefs_key_size = 64 if ( !$prefs_key_size );
+$prefs_val_size = 65536 if ( !$prefs_val_size );
if ( $ARGV[0] eq '--install-plugin' ) {
print "Activating plugin " . $ARGV[1] . "\n";
print "\n";
print "3. DSN for Preferences : $WHT$prefs_dsn$NRM\n";
print "4. Table for Preferences : $WHT$prefs_table$NRM\n";
- print "5. Field for username : $WHT$prefs_user_field$NRM\n";
- print "6. Field for prefs key : $WHT$prefs_key_field$NRM\n";
- print "7. Field for prefs value : $WHT$prefs_val_field$NRM\n";
+ print "5. Field for username : $WHT$prefs_user_field$NRM ($prefs_user_size)\n";
+ print "6. Field for prefs key : $WHT$prefs_key_field$NRM ($prefs_key_size)\n";
+ print "7. Field for prefs value : $WHT$prefs_val_field$NRM ($prefs_val_size)\n";
print "\n";
print "8. DSN for Global Address Book : $WHT$addrbook_global_dsn$NRM\n";
print "9. Table for Global Address Book : $WHT$addrbook_global_table$NRM\n";
} else {
$new_field =~ s/[\r\n]//g;
}
+ $prefs_user_size = db_pref_size($prefs_user_size);
return $new_field;
}
} else {
$new_field =~ s/[\r\n]//g;
}
+ $prefs_key_size = db_pref_size($prefs_key_size);
return $new_field;
}
} else {
$new_field =~ s/[\r\n]//g;
}
+ $prefs_val_size = db_pref_size($prefs_val_size);
return $new_field;
}
+# routine is used to set database field limits
+# it needs one argument
+sub db_pref_size() {
+ my ($size) = $_[0];
+ print "\nDatabase fields have size limits.\n";
+ print "\n";
+ print "What limit is set for this field? [$WHT$size$NRM]: $WHT";
+ $new_size = <STDIN>;
+ if ( $new_size eq "\n" ) {
+ $new_size = $size;
+ } else {
+ $new_size =~ s/[\r\n]//g;
+ }
+ return $new_size;
+}
+
sub command98 {
print "If you want to store your global address book in a database then\n";
print "you need to set this DSN to a valid value. The format for this is:\n";
print CF "\$prefs_table = '$prefs_table';\n";
# string
print CF "\$prefs_user_field = '$prefs_user_field';\n";
+ # integer
+ print CF "\$prefs_user_size = $prefs_user_size;\n";
# string
print CF "\$prefs_key_field = '$prefs_key_field';\n";
+ # integer
+ print CF "\$prefs_key_size = $prefs_key_size;\n";
# string
- print CF "\$prefs_val_field = '$prefs_val_field';\n\n";
+ print CF "\$prefs_val_field = '$prefs_val_field';\n";
+ # integer
+ print CF "\$prefs_val_size = $prefs_val_size;\n\n";
# string
print CF "\$addrbook_global_dsn = '$addrbook_global_dsn';\n";
# string
*/
$prefs_dsn = '';
$prefs_table = 'userprefs';
+/**
+ * Preference key field
+ * @global string $prefs_key_field
+ */
$prefs_key_field = 'prefkey';
+/**
+ * Size of preference key field
+ * @global integer $prefs_key_size
+ * @since 1.5.1
+ */
+$prefs_key_size = 64;
+/**
+ * Preference owner field
+ * @global string $prefs_user_field
+ */
$prefs_user_field = 'user';
+/**
+ * Size of preference owner field
+ * @global integer $prefs_user_size
+ * @since 1.5.1
+ */
+$prefs_user_size = 128;
+/**
+ * Preference value field
+ * @global string $prefs_val_field
+ */
$prefs_val_field = 'prefval';
+/**
+ * Size of preference key field
+ * @global integer $prefs_val_size
+ * @since 1.5.1
+ */
+$prefs_val_size = 65536;
/*** Global sql database options ***/
/**
Default preferences can be set by altering the $default array in
db_prefs.php.
+
+Troubleshooting
+---------------
+1. Oversized field values. Preferences are not/can't be saved
+
+Database fields have size limits. Preference table example sets 128
+character limit to owner field, 64 character limit to preference key
+field and 64KB (database BLOB field size) limit to value field.
+
+If interface tries to insert data without checking field limits, it
+can cause data loss or database errors. Table information functions
+provided by Pear DB libraries are not accurate and some database
+backends don't support them. Since 1.5.1 SquirrelMail provides
+configuration options that set allowed field sizes.
+
+If you see oversized field errors in your error logs - check your
+database structure. Issue can be solved by increasing database field
+sizes.
+
+If you want to get more debugging information - check setKey() function
+in dbPrefs class. Class is stored in functions/db_prefs.php
var $default = Array('theme_default' => 0,
'show_html_default' => '0');
+ /**
+ * Preference owner field size
+ * @var integer
+ * @since 1.5.1
+ */
+ var $user_size = 128;
+ /**
+ * Preference key field size
+ * @var integer
+ * @since 1.5.1
+ */
+ var $key_size = 64;
+ /**
+ * Preference value field size
+ * @var integer
+ * @since 1.5.1
+ */
+ var $val_size = 65536;
+
/**
* initialize DB connection object
* @return boolean true, if object is initialized
function open() {
global $prefs_dsn, $prefs_table;
global $prefs_user_field, $prefs_key_field, $prefs_val_field;
+ global $prefs_user_size, $prefs_key_size, $prefs_val_size;
if(isset($this->dbh)) {
return true;
if (!empty($prefs_val_field)) {
$this->val_field = $prefs_val_field;
}
+ if (!empty($prefs_user_size)) {
+ $this->user_size = (int) $prefs_user_size;
+ }
+ if (!empty($prefs_key_size)) {
+ $this->key_size = (int) $prefs_key_size;
+ }
+ if (!empty($prefs_val_size)) {
+ $this->val_size = (int) $prefs_val_size;
+ }
$dbh = DB::connect($prefs_dsn, true);
if(DB::isError($dbh)) {
if (!$this->open()) {
return false;
}
+
+ /**
+ * Check if username fits into db field
+ */
+ if (strlen($user) > $this->user_size) {
+ $this->error = "Oversized username value."
+ ." User's preferences can't be saved. See doc/db-backend.txt troubleshooting documentation.";
+
+ /**
+ * Debugging function. Can be used to log all issues that trigger
+ * oversized field errors. Function should be enabled in all three
+ * strlen checks. See http://www.php.net/error-log
+ */
+ // error_log($user.'|'.$key.'|'.$value."\n",3,'/tmp/oversized_log');
+
+ // error is fatal
+ $this->failQuery(null);
+ }
+ /**
+ * Check if preference key fits into db field
+ */
+ if (strlen($key) > $this->key_size) {
+ $err_msg = "Oversized user's preference key."
+ ." Some user preferences are not saved. See doc/db-backend.txt troubleshooting documentation.";
+ // error is not fatal. Only some preference is not saved.
+ trigger_error($err_msg,E_USER_WARNING);
+ return false;
+ }
+ /**
+ * Check if preference value fits into db field
+ */
+ if (strlen($value) > $this->val_size) {
+ $err_msg = "Oversized user's preference value."
+ ." Some user preferences are not saved. See doc/db-backend.txt troubleshooting documentation.";
+ // error is not fatal. Only some preference is not saved.
+ trigger_error($err_msg,E_USER_WARNING);
+ return false;
+ }
+
+
if ($this->db_type == SMDB_MYSQL) {
$query = sprintf("REPLACE INTO %s (%s, %s, %s) ".
"VALUES('%s','%s','%s')",
'type' => SMOPT_TYPE_STRING,
'size' => 40,
'default' => 'user' ),
+ '$prefs_user_size' => array( 'name' => _("Size of username field"),
+ 'type' => SMOPT_TYPE_INTEGER ),
'$prefs_key_field' => array('name' => _("Preferences key field"),
'type' => SMOPT_TYPE_STRING,
'size' => 40,
'default' => 'prefkey' ),
+ '$prefs_key_size' => array( 'name' => _("Size of key field"),
+ 'type' => SMOPT_TYPE_INTEGER ),
'$prefs_val_field' => array('name' => _("Preferences value field"),
'type' => SMOPT_TYPE_STRING,
'size' => 40,
'default' => 'prefval' ),
+ '$prefs_val_size' => array( 'name' => _("Size of value field"),
+ 'type' => SMOPT_TYPE_INTEGER ),
'$addrbook_global_dsn' => array( 'name' => _("Global address book DSN"),
'type' => SMOPT_TYPE_STRING,
'size' => 40 ),