View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0000834 | LDMud 3.6 | General | public | 2014-08-20 00:27 | 2021-04-06 21:31 |
Reporter | chaos | Assigned To | Gnomi | ||
Priority | normal | Severity | major | Reproducibility | always |
Status | resolved | Resolution | fixed | ||
Platform | amd64 | OS | Debian | OS Version | 2.6.18-5 |
Fixed in Version | 3.6.4 | ||||
Summary | 0000834: Quoted arrays inside arrays or mappings save correctly but error on restore | ||||
Description | Serialization of quoted arrays inside arrays or mappings results in a spurious format error on restore_svalue(). | ||||
Steps To Reproduce | restore_value(save_value(({ '({}) }))) | ||||
Additional Information | This happens because ({ is a valid operator per symbol_operator(), which causes restore_size() and restore_map_size() to return inaccurate results when the data structure contains a quoted array. I fixed this locally by wrapping the usage of symbol_operator() in restore_size() and restore_map_size() in this: /* Specially avoid quoted arrays since symbol_operator(), if * called now, will think their opening construct is an operator */ if(*pt != '(' || *(pt + 1) != '{') { ... } The relevant code is identical in the 3.2 branch; I'd suggest this would be a valid update to reopen this branch for, since it's a potentially serious bug and very easily resolved. | ||||
Tags | No tags attached. | ||||
|
BTW: My fix would leave the case of an actual serialized #'({ unaddressed and presumably not working, except that #'({ is serialized as #e:aggregate, not #e:({, so it seems like it should be fine. |
|
It turns out that my fix continues to fail in the case of quoted arrays with sharing specifiers, like #1:<1>=({1,2,}) For a more robust fix, I added this function (before restore_map_size()): /*-------------------------------------------------------------------------*/ /* Detects whether we are at the beginning of an array literal in * a serialized data string */ INLINE static int at_array_literal (char *pt) { if (*pt == '(' && *(pt + 1) == '{') return MY_TRUE; if (*pt != '<') return MY_FALSE; switch (*++pt) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': for (pt++; *pt != '>'; pt++) { switch (*pt) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '>': break; default : return MY_FALSE; } } break; default : return MY_FALSE; } return *(pt + 1) == '=' && *(pt + 2) == '(' && *(pt + 3) == '{'; } and replaced the logic I originally gave with if (!at_array_literal(pt)). |
Date Modified | Username | Field | Change |
---|---|---|---|
2014-08-20 00:27 | chaos | New Issue | |
2014-08-20 13:12 | chaos | Note Added: 0002238 | |
2014-09-14 06:06 | chaos | Note Added: 0002241 | |
2014-09-14 06:07 | chaos | Note Edited: 0002241 | |
2014-09-14 06:07 | chaos | Note Edited: 0002241 | |
2014-09-14 06:08 | chaos | Note Edited: 0002241 | |
2014-09-14 06:08 | chaos | Note Edited: 0002241 | |
2014-09-14 06:10 | chaos | Note Edited: 0002241 | |
2020-11-12 15:23 | Gnomi | Assigned To | => Gnomi |
2020-11-12 15:23 | Gnomi | Status | new => assigned |
2021-04-06 21:31 | Gnomi | Project | LDMud 3.3 => LDMud 3.6 |
2021-04-06 21:31 | Gnomi | Category | LPC Language => General |
2021-04-06 21:31 | Gnomi | Status | assigned => resolved |
2021-04-06 21:31 | Gnomi | Resolution | open => fixed |
2021-04-06 21:31 | Gnomi | Fixed in Version | => 3.6.4 |