mirror of https://github.com/djcb/mu.git
* make time & size checking a bit stricter, report errors to user
This commit is contained in:
parent
199c6c9bd9
commit
6c62a066c8
|
@ -45,32 +45,18 @@ public:
|
|||
|
||||
if (!clear_prefix (begin))
|
||||
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 (end);
|
||||
substitute_date (begin, true);
|
||||
substitute_date (end, false);
|
||||
|
||||
normalize_date (begin);
|
||||
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);
|
||||
|
||||
if (begin > end)
|
||||
throw Xapian::QueryParserError ("end time is before begin");
|
||||
|
||||
return (Xapian::valueno)MU_MSG_PSEUDO_FIELD_ID_DATESTR;
|
||||
}
|
||||
|
@ -93,13 +79,15 @@ private:
|
|||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void substitute_date (std::string& date) {
|
||||
void substitute_date (std::string& date, bool is_begin) {
|
||||
char datebuf[13];
|
||||
time_t now = time(NULL);
|
||||
|
||||
if (date == "today") {
|
||||
strftime(datebuf, sizeof(datebuf), "%Y%m%d0000",
|
||||
strftime(datebuf, sizeof(datebuf),
|
||||
is_begin ? "%Y%m%d0000" : "%Y%m%d2359",
|
||||
localtime(&now));
|
||||
date = datebuf;
|
||||
} else if (date == "now") {
|
||||
|
@ -189,9 +177,9 @@ private:
|
|||
|
||||
bool substitute_size (std::string& size) {
|
||||
gchar str[16];
|
||||
guint64 num = mu_str_size_parse_kmg (size.c_str());
|
||||
if (num == G_MAXUINT64)
|
||||
return false;
|
||||
gint64 num = mu_str_size_parse_bkm(size.c_str());
|
||||
if (num < 0)
|
||||
throw Xapian::QueryParserError ("invalid size");
|
||||
snprintf (str, sizeof(str), "%" G_GUINT64_FORMAT, num);
|
||||
size = str;
|
||||
return true;
|
||||
|
@ -243,8 +231,8 @@ get_query (MuQuery *mqx, const char* searchexpr, GError **err)
|
|||
|
||||
} catch (...) {
|
||||
/* some error occured */
|
||||
g_set_error (err, 0, MU_ERROR_QUERY, "parse error in query '%s'",
|
||||
searchexpr);
|
||||
g_set_error (err, 0, MU_ERROR_QUERY,
|
||||
"parse error in query");
|
||||
g_free (preprocessed);
|
||||
throw;
|
||||
}
|
||||
|
|
|
@ -314,7 +314,7 @@ static void
|
|||
add_terms_values_date (Xapian::Document& doc, MuMsg *msg,
|
||||
MuMsgFieldId mfid)
|
||||
{
|
||||
char datebuf[13]; /* YYYYMMDDHHMMSS */
|
||||
char datebuf[13]; /* YYYYMMDDHHMM\0 */
|
||||
static const std::string pfx (1, mu_msg_field_xapian_prefix(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;
|
||||
}
|
||||
|
||||
guint64
|
||||
mu_str_size_parse_kmg (const char* str)
|
||||
gint64
|
||||
mu_str_size_parse_bkm (const char* str)
|
||||
{
|
||||
gint64 num;
|
||||
char *end;
|
||||
|
||||
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;
|
||||
}
|
||||
const char *cur;
|
||||
|
||||
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
|
||||
* unit. Units recognized are K (1000) and M (1000*1000). Only the
|
||||
* first letter is checked and the function is not case-sensitive, so
|
||||
* 1000Kb, 3M will work equally well. Note, for kB, MB etc., we then
|
||||
* follow the SI standards, not 2^10 etc.
|
||||
* unit. Units recognized are b/B (bytes) k/K (1000) and m/M
|
||||
* (1000*1000). Only the first letter is checked and the function is
|
||||
* not case-sensitive, so 1000Kb, 3M will work equally well. Note,
|
||||
* 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
|
||||
* 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"
|
||||
*
|
||||
* @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_
|
||||
|
|
|
@ -347,13 +347,13 @@ test_mu_query_dates (void)
|
|||
|
||||
QResults queries[] = {
|
||||
{ "date:20080731..20080804", 5},
|
||||
{ "date:20080804..20080731", 5},
|
||||
/* { "date:20080804..20080731", 5}, */
|
||||
{ "date:2008-07/31..2008@08:04", 5},
|
||||
{ "date:2008-0731..20080804 s:gcc", 1},
|
||||
{ "date:2008-08-11-08-03..now", 1},
|
||||
{ "date:2008-08-11-08-03..today", 1},
|
||||
{ "date:now..2008-08-11-08-03", 1},
|
||||
{ "date:today..2008-08-11-08-03", 1},
|
||||
/* { "date:now..2008-08-11-08-03", 1}, */
|
||||
/* { "date:today..2008-08-11-08-03", 1}, */
|
||||
{ "date:2008-08-11-08-05..now", 0},
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue