Skip to content

Commit 963acd5

Browse files
committed
lib: add diagnostic substitute class for ec_error_t
Similar to errno_t, make ec_error_t a struct that prohibits use of bool conversions to detect misuses of ec_error_t return values.
1 parent d8d4ec2 commit 963acd5

File tree

8 files changed

+59
-22
lines changed

8 files changed

+59
-22
lines changed

.github/workflows/build.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,6 @@ jobs:
4040
./qconf
4141
LD_LIBRARY_PATH=/usr/local/lib make "-j$(nproc)"
4242
LD_LIBRARY_PATH=/usr/local/lib make install DESTDIR="$PWD/rt" && rm -Rf rt
43+
make clean
44+
LD_LIBRARY_PATH=/usr/local/lib make "-j$(nproc)" CPPFLAGS=-DCOMPILE_DIAG
4345
make distclean

exch/zcore/common_util.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1215,7 +1215,9 @@ static ec_error_t cu_rcpt_to_list(eid_t message_id, const TPROPVAL_ARRAY &props,
12151215
g_org_name, cu_id2user, es_result);
12161216
if (ret == ecSuccess)
12171217
list.emplace_back(std::move(es_result));
1218-
return ret == ecNullObject || ret == ecUnknownUser ? ecInvalidRecips : ret;
1218+
if (ret == ecNullObject || ret == ecUnknownUser)
1219+
return ecInvalidRecips;
1220+
return ret;
12191221
} catch (const std::bad_alloc &) {
12201222
mlog(LV_ERR, "E-1122: ENOMEM");
12211223
return ecServerOOM;
@@ -1361,7 +1363,7 @@ void common_util_notify_receipt(const char *username, int type,
13611363
auto ret = cu_send_vmail(std::move(imail), g_smtp_url.c_str(),
13621364
username, rcpt_list);
13631365
if (ret != ecSuccess)
1364-
mlog(LV_ERR, "E-1193: cu_send_mail: %xh", ret);
1366+
mlog(LV_ERR, "E-1193: cu_send_mail: %xh", static_cast<unsigned int>(ret));
13651367
} catch (const std::bad_alloc &) {
13661368
mlog(LV_ERR, "E-2038: ENOMEM");
13671369
}

exch/zcore/object_tree.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ std::unique_ptr<OBJECT_TREE> object_tree_create(const char *maildir)
263263
if (prootobj == nullptr)
264264
return NULL;
265265
auto handle = pobjtree->add_object_handle(-1, {zs_objtype::root, std::move(prootobj)});
266-
if (zh_error(handle))
266+
if (zh_is_error(handle))
267267
return nullptr;
268268
return pobjtree;
269269
}

exch/zcore/object_tree.hpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,14 @@
88

99
static inline ec_error_t zh_error(uint32_t h)
1010
{
11-
return h < 0x80000000 ? ecSuccess : static_cast<ec_error_t>(h);
11+
if (h >= 0x80000000)
12+
return static_cast<ec_error_t>(h);
13+
return ecSuccess;
14+
}
15+
16+
static inline bool zh_is_error(uint32_t h)
17+
{
18+
return h >= 0x80000000;
1219
}
1320

1421
struct object_node {

exch/zcore/rpc_parser.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,12 +88,12 @@ static int rpc_parser_dispatch(const zcreq *q0, std::unique_ptr<zcresp> &r0) try
8888
r0->call_id = q0->call_id;
8989
if (g_zrpc_debug == 0)
9090
return DISPATCH_TRUE;
91-
if (r0->result != 0 || g_zrpc_debug == 2) {
91+
if (r0->result != ecSuccess || g_zrpc_debug == 2) {
9292
auto info = zs_query_session(dbg_hsession);
9393
mlog(LV_DEBUG, "ZRPC %s %5luµs %8xh %s",
9494
info != nullptr ? info->username.c_str() : "<>",
9595
static_cast<unsigned long>(std::chrono::duration_cast<std::chrono::microseconds>(tend - tstart).count()),
96-
r0->result, zcore_rpc_idtoname(q0->call_id));
96+
static_cast<unsigned int>(r0->result), zcore_rpc_idtoname(q0->call_id));
9797
}
9898
return DISPATCH_TRUE;
9999
} catch (const std::bad_alloc &) {

exch/zcore/zserver.cpp

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -842,7 +842,7 @@ ec_error_t zs_openentry(GUID hsession, BINARY entryid,
842842
&b_private, &account_id, &folder_id))
843843
break;
844844
auto handle = pinfo->ptree->get_store_handle(b_private, account_id);
845-
if (zh_error(handle))
845+
if (zh_is_error(handle))
846846
return zh_error(handle);
847847
pinfo.reset();
848848
return zs_openstoreentry(hsession,
@@ -854,7 +854,7 @@ ec_error_t zs_openentry(GUID hsession, BINARY entryid,
854854
&b_private, &account_id, &folder_id, &message_id))
855855
break;
856856
auto handle = pinfo->ptree->get_store_handle(b_private, account_id);
857-
if (zh_error(handle))
857+
if (zh_is_error(handle))
858858
return zh_error(handle);
859859
pinfo.reset();
860860
return zs_openstoreentry(hsession,
@@ -1030,7 +1030,7 @@ ec_error_t zs_openstoreentry(GUID hsession, uint32_t hobject, BINARY entryid,
10301030
if (pmessage == nullptr)
10311031
return ecError;
10321032
*phobject = pinfo->ptree->add_object_handle(hobject, {zs_objtype::message, std::move(pmessage)});
1033-
if (zh_error(*phobject))
1033+
if (zh_is_error(*phobject))
10341034
return zh_error(*phobject);
10351035
*pmapi_type = zs_objtype::message;
10361036
} else {
@@ -1084,7 +1084,7 @@ ec_error_t zs_openstoreentry(GUID hsession, uint32_t hobject, BINARY entryid,
10841084
if (pfolder == nullptr)
10851085
return ecError;
10861086
*phobject = pinfo->ptree->add_object_handle(hobject, {zs_objtype::folder, std::move(pfolder)});
1087-
if (zh_error(*phobject))
1087+
if (zh_is_error(*phobject))
10881088
return zh_error(*phobject);
10891089
*pmapi_type = zs_objtype::folder;
10901090
}
@@ -1126,7 +1126,7 @@ ec_error_t zs_openabentry(GUID hsession,
11261126
return ecError;
11271127
*pmapi_type = zs_objtype::abcont;
11281128
*phobject = pinfo->ptree->add_object_handle(ROOT_HANDLE, {*pmapi_type, std::move(contobj)});
1129-
if (zh_error(*phobject))
1129+
if (zh_is_error(*phobject))
11301130
return zh_error(*phobject);
11311131
return ecSuccess;
11321132
}
@@ -1237,7 +1237,7 @@ static ec_error_t zs_openab_emsab(USER_INFO_REF &&pinfo, BINARY entryid,
12371237
} else {
12381238
return ecInvalidParam;
12391239
}
1240-
if (zh_error(*phobject))
1240+
if (zh_is_error(*phobject))
12411241
return zh_error(*phobject);
12421242
return ecSuccess;
12431243
}
@@ -1639,7 +1639,7 @@ ec_error_t zs_createmessage(GUID hsession,
16391639
auto folder_id = pfolder->folder_id;
16401640
auto pstore = pfolder->pstore;
16411641
auto hstore = pinfo->ptree->get_store_handle(pstore->b_private, pstore->account_id);
1642-
if (zh_error(hstore))
1642+
if (zh_is_error(hstore))
16431643
return zh_error(hstore);
16441644
if (!pstore->owner_mode()) {
16451645
if (!exmdb_client->get_folder_perm(pstore->get_dir(),
@@ -2142,7 +2142,7 @@ ec_error_t zs_createfolder(GUID hsession, uint32_t hparent_folder,
21422142
because the caller normally will not keep the
21432143
handle of parent folder */
21442144
auto hstore = pinfo->ptree->get_store_handle(TRUE, pstore->account_id);
2145-
if (zh_error(hstore))
2145+
if (zh_is_error(hstore))
21462146
return zh_error(hstore);
21472147
*phobject = pinfo->ptree->add_object_handle(hstore, {zs_objtype::folder, std::move(pfolder)});
21482148
} else {
@@ -3826,7 +3826,7 @@ ec_error_t zs_openembedded(GUID hsession,
38263826
return ecNotSupported;
38273827
auto pstore = pattachment->get_store();
38283828
auto hstore = pinfo->ptree->get_store_handle(pstore->b_private, pstore->account_id);
3829-
if (zh_error(hstore))
3829+
if (zh_is_error(hstore))
38303830
return zh_error(hstore);
38313831
auto b_writable = pattachment->writable();
38323832
auto tag_access = pattachment->get_tag_access();
@@ -4073,7 +4073,7 @@ ec_error_t zs_hierarchysync(GUID hsession, uint32_t hfolder, uint32_t *phobject)
40734073
return ecNotSupported;
40744074
auto pstore = pfolder->pstore;
40754075
auto hstore = pinfo->ptree->get_store_handle(pstore->b_private, pstore->account_id);
4076-
if (zh_error(hstore))
4076+
if (zh_is_error(hstore))
40774077
return zh_error(hstore);
40784078
auto pctx = icsdownctx_object::create(pfolder, SYNC_TYPE_HIERARCHY);
40794079
if (pctx == nullptr)
@@ -4095,7 +4095,7 @@ ec_error_t zs_contentsync(GUID hsession, uint32_t hfolder, uint32_t *phobject)
40954095
return ecNotSupported;
40964096
auto pstore = pfolder->pstore;
40974097
auto hstore = pinfo->ptree->get_store_handle(pstore->b_private, pstore->account_id);
4098-
if (zh_error(hstore))
4098+
if (zh_is_error(hstore))
40994099
return zh_error(hstore);
41004100
auto pctx = icsdownctx_object::create(pfolder, SYNC_TYPE_CONTENTS);
41014101
if (pctx == nullptr)
@@ -4229,7 +4229,7 @@ ec_error_t zs_hierarchyimport(GUID hsession,
42294229
return ecNotSupported;
42304230
auto pstore = pfolder->pstore;
42314231
auto hstore = pinfo->ptree->get_store_handle(pstore->b_private, pstore->account_id);
4232-
if (zh_error(hstore))
4232+
if (zh_is_error(hstore))
42334233
return zh_error(hstore);
42344234
auto pctx = icsupctx_object::create(pfolder, SYNC_TYPE_HIERARCHY);
42354235
if (pctx == nullptr)
@@ -4251,7 +4251,7 @@ ec_error_t zs_contentimport(GUID hsession, uint32_t hfolder, uint32_t *phobject)
42514251
return ecNotSupported;
42524252
auto pstore = pfolder->pstore;
42534253
auto hstore = pinfo->ptree->get_store_handle(pstore->b_private, pstore->account_id);
4254-
if (zh_error(hstore))
4254+
if (zh_is_error(hstore))
42554255
return zh_error(hstore);
42564256
auto pctx = icsupctx_object::create(pfolder, SYNC_TYPE_CONTENTS);
42574257
if (pctx == nullptr)
@@ -5152,7 +5152,7 @@ ec_error_t zs_linkmessage(GUID hsession,
51525152
if (pinfo == nullptr)
51535153
return ecError;
51545154
auto handle = pinfo->ptree->get_store_handle(b_private, account_id);
5155-
if (zh_error(handle))
5155+
if (zh_is_error(handle))
51565156
return zh_error(handle);
51575157
if (pinfo->user_id < 0)
51585158
return ecAccessDenied;

include/gromox/mapierr.hpp

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,12 @@
1414
*
1515
* -- Changes here should be reflected in lib/errno.cpp.
1616
*/
17-
enum ec_error_t {
17+
#ifdef COMPILE_DIAG
18+
enum ec_error_t_ll
19+
#else
20+
enum ec_error_t
21+
#endif
22+
{
1823
ecSuccess = 0, // ecNone
1924
MAPI_E_UNBINDSUCCESS = 1, /* NSPI */
2025
// MAPI_E_USER_ABORT = 0x1,
@@ -429,3 +434,19 @@ enum ec_error_t {
429434
ecZNullObject = 0xfffffc00,
430435
ecZOutOfHandles = 0xfffffc04,
431436
};
437+
438+
#ifdef COMPILE_DIAG
439+
struct ec_error_t {
440+
constexpr ec_error_t() = default;
441+
constexpr ec_error_t(uint32_t x) : m_value(static_cast<ec_error_t_ll>(x)) {}
442+
constexpr ec_error_t(ec_error_t_ll x) : m_value(x) {}
443+
constexpr ec_error_t(int) = delete;
444+
constexpr bool operator==(ec_error_t_ll x) const { return m_value == x; }
445+
constexpr bool operator!=(ec_error_t_ll x) const { return m_value != x; }
446+
constexpr operator bool() const = delete;
447+
constexpr void operator!() const = delete;
448+
constexpr operator uint32_t() const { return m_value; }
449+
private:
450+
ec_error_t_ll m_value = ecSuccess;
451+
};
452+
#endif

lib/rfbl.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,12 @@ const char *mapi_errname_r(unsigned int e, char *b, size_t bz)
194194
const char *mapi_strerror(ec_error_t e)
195195
{
196196
// STG = storage
197-
switch (e) {
197+
#ifdef COMPILE_DIAG
198+
switch (static_cast<uint32_t>(e))
199+
#else
200+
switch (e)
201+
#endif
202+
{
198203
#define E(v, s) case v: return s;
199204
E(ecSuccess, "The operation succeeded")
200205
E(ecUnknownUser, "User is unknown to the system")

0 commit comments

Comments
 (0)