* make time & size checking a bit stricter, report errors to user
This commit is contained in:
@ -45,32 +45,18 @@ public:
|
|||||||
|
|
||||||
if (!clear_prefix (begin))
|
if (!clear_prefix (begin))
|
||||||
return Xapian::BAD_VALUENO;
|
return Xapian::BAD_VALUENO;
|
||||||
|
|
||||||
// now and begin should only appear at the end, so
|
|
||||||
// correct them...
|
|
||||||
if (begin == "today" || begin == "now")
|
|
||||||
std::swap (begin, end);
|
|
||||||
|
|
||||||
substitute_date (begin);
|
substitute_date (begin, true);
|
||||||
substitute_date (end);
|
substitute_date (end, false);
|
||||||
|
|
||||||
normalize_date (begin);
|
normalize_date (begin);
|
||||||
normalize_date (end);
|
normalize_date (end);
|
||||||
|
|
||||||
// note, we'll have to compare the *completed*
|
|
||||||
// versions of begin and end to if the were specified
|
|
||||||
// in the opposite order; however, if that is true, we
|
|
||||||
// have to complete begin, end 'for real', as the
|
|
||||||
// begin date is completed to the begin of the
|
|
||||||
// interval, and the to the end of the interval
|
|
||||||
// ie. begin: 2008 -> 200801010000 end: 2008 ->
|
|
||||||
// 200812312359
|
|
||||||
if (complete_date12(begin,true) >
|
|
||||||
complete_date12(end, false))
|
|
||||||
std::swap (begin, end);
|
|
||||||
|
|
||||||
begin = complete_date12(begin,true);
|
begin = complete_date12(begin, true);
|
||||||
end = complete_date12(end, false);
|
end = complete_date12(end, false);
|
||||||
|
|
||||||
|
if (begin > end)
|
||||||
|
throw Xapian::QueryParserError ("end time is before begin");
|
||||||
|
|
||||||
return (Xapian::valueno)MU_MSG_PSEUDO_FIELD_ID_DATESTR;
|
return (Xapian::valueno)MU_MSG_PSEUDO_FIELD_ID_DATESTR;
|
||||||
}
|
}
|
||||||
@ -93,13 +79,15 @@ private:
|
|||||||
} else
|
} else
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void substitute_date (std::string& date) {
|
void substitute_date (std::string& date, bool is_begin) {
|
||||||
char datebuf[13];
|
char datebuf[13];
|
||||||
time_t now = time(NULL);
|
time_t now = time(NULL);
|
||||||
|
|
||||||
if (date == "today") {
|
if (date == "today") {
|
||||||
strftime(datebuf, sizeof(datebuf), "%Y%m%d0000",
|
strftime(datebuf, sizeof(datebuf),
|
||||||
|
is_begin ? "%Y%m%d0000" : "%Y%m%d2359",
|
||||||
localtime(&now));
|
localtime(&now));
|
||||||
date = datebuf;
|
date = datebuf;
|
||||||
} else if (date == "now") {
|
} else if (date == "now") {
|
||||||
@ -189,9 +177,9 @@ private:
|
|||||||
|
|
||||||
bool substitute_size (std::string& size) {
|
bool substitute_size (std::string& size) {
|
||||||
gchar str[16];
|
gchar str[16];
|
||||||
guint64 num = mu_str_size_parse_kmg (size.c_str());
|
gint64 num = mu_str_size_parse_bkm(size.c_str());
|
||||||
if (num == G_MAXUINT64)
|
if (num < 0)
|
||||||
return false;
|
throw Xapian::QueryParserError ("invalid size");
|
||||||
snprintf (str, sizeof(str), "%" G_GUINT64_FORMAT, num);
|
snprintf (str, sizeof(str), "%" G_GUINT64_FORMAT, num);
|
||||||
size = str;
|
size = str;
|
||||||
return true;
|
return true;
|
||||||
@ -243,8 +231,8 @@ get_query (MuQuery *mqx, const char* searchexpr, GError **err)
|
|||||||
|
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
/* some error occured */
|
/* some error occured */
|
||||||
g_set_error (err, 0, MU_ERROR_QUERY, "parse error in query '%s'",
|
g_set_error (err, 0, MU_ERROR_QUERY,
|
||||||
searchexpr);
|
"parse error in query");
|
||||||
g_free (preprocessed);
|
g_free (preprocessed);
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -314,7 +314,7 @@ static void
|
|||||||
add_terms_values_date (Xapian::Document& doc, MuMsg *msg,
|
add_terms_values_date (Xapian::Document& doc, MuMsg *msg,
|
||||||
MuMsgFieldId mfid)
|
MuMsgFieldId mfid)
|
||||||
{
|
{
|
||||||
char datebuf[13]; /* YYYYMMDDHHMMSS */
|
char datebuf[13]; /* YYYYMMDDHHMM\0 */
|
||||||
static const std::string pfx (1, mu_msg_field_xapian_prefix(mfid));
|
static const std::string pfx (1, mu_msg_field_xapian_prefix(mfid));
|
||||||
gint64 num = mu_msg_get_field_numeric (msg, mfid);
|
gint64 num = mu_msg_get_field_numeric (msg, mfid);
|
||||||
|
|
||||||
|
|||||||
40
src/mu-str.c
40
src/mu-str.c
@ -345,30 +345,28 @@ mu_str_date_parse_hdwmy (const char *nptr)
|
|||||||
return delta <= now ? now - delta : never;
|
return delta <= now ? now - delta : never;
|
||||||
}
|
}
|
||||||
|
|
||||||
guint64
|
gint64
|
||||||
mu_str_size_parse_kmg (const char* str)
|
mu_str_size_parse_bkm (const char* str)
|
||||||
{
|
{
|
||||||
gint64 num;
|
gint64 num;
|
||||||
char *end;
|
const char *cur;
|
||||||
|
|
||||||
g_return_val_if_fail (str, G_MAXUINT64);
|
|
||||||
|
|
||||||
num = strtol (str, &end, 10);
|
|
||||||
if (num < 0)
|
|
||||||
return G_MAXUINT64;
|
|
||||||
|
|
||||||
if (!end || end[1] != '\0')
|
|
||||||
return G_MAXUINT64;
|
|
||||||
|
|
||||||
switch (tolower(end[0])) {
|
|
||||||
case 'b': return num; /* bytes */
|
|
||||||
case 'k': return num * 1000; /* kilobyte */
|
|
||||||
case 'm': return num * 1000 * 1000; /* megabyte */
|
|
||||||
/* case 'g': return num * 1000 * 1000 * 1000; /\* gigabyte *\/ */
|
|
||||||
default:
|
|
||||||
return G_MAXUINT64;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
g_return_val_if_fail (str, -1);
|
||||||
|
|
||||||
|
if (!isdigit(str[0]))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
num = atoi(str);
|
||||||
|
for (++str; isdigit(*str); ++str);
|
||||||
|
|
||||||
|
switch (tolower(*str)) {
|
||||||
|
case '\0':
|
||||||
|
case 'b' : return num; /* bytes */
|
||||||
|
case 'k': return num * 1000; /* kilobyte */
|
||||||
|
case 'm': return num * 1000 * 1000; /* megabyte */
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
13
src/mu-str.h
13
src/mu-str.h
@ -215,10 +215,11 @@ time_t mu_str_date_parse_hdwmy (const char* str);
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* parse a byte size; a size is a number, with optionally a
|
* parse a byte size; a size is a number, with optionally a
|
||||||
* unit. Units recognized are K (1000) and M (1000*1000). Only the
|
* unit. Units recognized are b/B (bytes) k/K (1000) and m/M
|
||||||
* first letter is checked and the function is not case-sensitive, so
|
* (1000*1000). Only the first letter is checked and the function is
|
||||||
* 1000Kb, 3M will work equally well. Note, for kB, MB etc., we then
|
* not case-sensitive, so 1000Kb, 3M will work equally well. Note,
|
||||||
* follow the SI standards, not 2^10 etc.
|
* for kB, MB etc., we then follow the SI standards, not 2^10 etc. The
|
||||||
|
* 'b' may be omitted.
|
||||||
*
|
*
|
||||||
* practical sizes for email messages are in terms of Mb; even in
|
* practical sizes for email messages are in terms of Mb; even in
|
||||||
* extreme cases it should be under 100 Mb. Function return
|
* extreme cases it should be under 100 Mb. Function return
|
||||||
@ -226,9 +227,9 @@ time_t mu_str_date_parse_hdwmy (const char* str);
|
|||||||
*
|
*
|
||||||
* @param str a string with a size, such a "100", "100Kb", "1Mb"
|
* @param str a string with a size, such a "100", "100Kb", "1Mb"
|
||||||
*
|
*
|
||||||
* @return the corresponding time_t value (as a guint64)
|
* @return the corresponding size in bytes, or -1 in case of error
|
||||||
*/
|
*/
|
||||||
guint64 mu_str_size_parse_kmg (const char* str);
|
gint64 mu_str_size_parse_bkm (const char* str);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* create a full path from a path + a filename. function is _not_
|
* create a full path from a path + a filename. function is _not_
|
||||||
|
|||||||
@ -347,13 +347,13 @@ test_mu_query_dates (void)
|
|||||||
|
|
||||||
QResults queries[] = {
|
QResults queries[] = {
|
||||||
{ "date:20080731..20080804", 5},
|
{ "date:20080731..20080804", 5},
|
||||||
{ "date:20080804..20080731", 5},
|
/* { "date:20080804..20080731", 5}, */
|
||||||
{ "date:2008-07/31..2008@08:04", 5},
|
{ "date:2008-07/31..2008@08:04", 5},
|
||||||
{ "date:2008-0731..20080804 s:gcc", 1},
|
{ "date:2008-0731..20080804 s:gcc", 1},
|
||||||
{ "date:2008-08-11-08-03..now", 1},
|
{ "date:2008-08-11-08-03..now", 1},
|
||||||
{ "date:2008-08-11-08-03..today", 1},
|
{ "date:2008-08-11-08-03..today", 1},
|
||||||
{ "date:now..2008-08-11-08-03", 1},
|
/* { "date:now..2008-08-11-08-03", 1}, */
|
||||||
{ "date:today..2008-08-11-08-03", 1},
|
/* { "date:today..2008-08-11-08-03", 1}, */
|
||||||
{ "date:2008-08-11-08-05..now", 0},
|
{ "date:2008-08-11-08-05..now", 0},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user