diff options
author | Alex Gorrod <alexander.gorrod@mongodb.com> | 2016-06-01 12:38:19 +1000 |
---|---|---|
committer | Alex Gorrod <alexander.gorrod@mongodb.com> | 2016-06-01 12:38:19 +1000 |
commit | ff108d7c705b82e482fb17e33488dc14304bf259 (patch) | |
tree | 6cdc57dd2b037f9f61848ba1eae74c214b406e6a /src/cursor | |
parent | 6f9a7a41f21476235b0bb99f0f16a2d7f738c2e0 (diff) | |
parent | 7033ed47f3986edb08ec8c4933e6ef211e73b3c4 (diff) | |
download | mongo-ff108d7c705b82e482fb17e33488dc14304bf259.tar.gz |
Merge branch 'develop' into mongodb-3.4
Diffstat (limited to 'src/cursor')
-rw-r--r-- | src/cursor/cur_dump.c | 21 | ||||
-rw-r--r-- | src/cursor/cur_json.c | 98 |
2 files changed, 66 insertions, 53 deletions
diff --git a/src/cursor/cur_dump.c b/src/cursor/cur_dump.c index a7b1c98871a..32353e0a28d 100644 --- a/src/cursor/cur_dump.c +++ b/src/cursor/cur_dump.c @@ -155,7 +155,9 @@ __curdump_set_key(WT_CURSOR *cursor, ...) WT_SESSION_IMPL *session; uint64_t recno; va_list ap; + const uint8_t *up; const char *p; + bool json; cdump = (WT_CURSOR_DUMP *)cursor; child = cdump->child; @@ -168,16 +170,23 @@ __curdump_set_key(WT_CURSOR *cursor, ...) p = va_arg(ap, const char *); va_end(ap); + json = F_ISSET(cursor, WT_CURSTD_DUMP_JSON); + if (json) + WT_ERR(__wt_json_to_item(session, p, cursor->key_format, + (WT_CURSOR_JSON *)cursor->json_private, true, + &cursor->key)); + if (WT_CURSOR_RECNO(cursor) && !F_ISSET(cursor, WT_CURSTD_RAW)) { - WT_ERR(str2recno(session, p, &recno)); + if (json) { + up = (const uint8_t *)cursor->key.data; + WT_ERR(__wt_vunpack_uint(&up, cursor->key.size, + &recno)); + } else + WT_ERR(str2recno(session, p, &recno)); child->set_key(child, recno); } else { - if (F_ISSET(cursor, WT_CURSTD_DUMP_JSON)) - WT_ERR(__wt_json_to_item(session, p, cursor->key_format, - (WT_CURSOR_JSON *)cursor->json_private, true, - &cursor->key)); - else + if (!json) WT_ERR(__dump_to_raw(session, p, &cursor->key, F_ISSET(cursor, WT_CURSTD_DUMP_HEX))); diff --git a/src/cursor/cur_json.c b/src/cursor/cur_json.c index fcb66d3e8b3..133b7b9ac9b 100644 --- a/src/cursor/cur_json.c +++ b/src/cursor/cur_json.c @@ -48,6 +48,10 @@ static int __json_pack_size(WT_SESSION_IMPL *, const char *, WT_CONFIG_ITEM *, case 't': \ WT_RET(json_uint_arg(session, &jstr, &pv.u.u)); \ break; \ + case 'u': \ + WT_RET(json_string_arg(session, &jstr, &pv.u.item)); \ + pv.type = 'K'; \ + break; \ /* User format strings have already been validated. */ \ WT_ILLEGAL_VALUE(session); \ } \ @@ -493,7 +497,7 @@ __wt_json_token(WT_SESSION *wt_session, const char *src, int *toktype, "invalid Unicode within JSON string"); return (-1); } - src += 5; + src += 4; } backslash = false; } @@ -840,20 +844,17 @@ __wt_json_strlen(const char *src, size_t srclen) if (__wt_hex2byte((const u_char *)src, &lo)) return (-1); src += 2; - /* RFC 3629 */ - if (hi >= 0x8) { - /* 3 bytes total */ - dstlen += 2; - } - else if (hi != 0 || lo >= 0x80) { - /* 2 bytes total */ - dstlen++; - } - /* else 1 byte total */ + if (hi != 0) + /* + * For our dump representation, + * every Unicode character on input + * represents a single byte. + */ + return (-1); } - } + } else + src++; dstlen++; - src++; } if (src != srcend) return (-1); /* invalid input, e.g. final char is '\\' */ @@ -867,55 +868,58 @@ __wt_json_strlen(const char *src, size_t srclen) * the result if zero padded. */ int -__wt_json_strncpy(char **pdst, size_t dstlen, const char *src, size_t srclen) +__wt_json_strncpy(WT_SESSION *wt_session, char **pdst, size_t dstlen, + const char *src, size_t srclen) { - char *dst; + WT_SESSION_IMPL *session; + char ch, *dst; const char *dstend, *srcend; u_char hi, lo; + session = (WT_SESSION_IMPL *)wt_session; + dst = *pdst; dstend = dst + dstlen; srcend = src + srclen; while (src < srcend && dst < dstend) { /* JSON can include any UTF-8 expressed in 4 hex chars. */ - if (*src == '\\') { - if (*++src == 'u') { - if (__wt_hex2byte((const u_char *)++src, &hi)) + if ((ch = *src++) == '\\') + switch (ch = *src++) { + case 'u': + if (__wt_hex2byte((const u_char *)src, &hi)) return (EINVAL); src += 2; if (__wt_hex2byte((const u_char *)src, &lo)) return (EINVAL); src += 2; - /* RFC 3629 */ - if (hi >= 0x8) { - /* 3 bytes total */ - /* byte 0: 1110HHHH */ - /* byte 1: 10HHHHLL */ - /* byte 2: 10LLLLLL */ - *dst++ = (char)(0xe0 | - ((hi >> 4) & 0x0f)); - *dst++ = (char)(0x80 | - ((hi << 2) & 0x3c) | - ((lo >> 6) & 0x03)); - *dst++ = (char)(0x80 | (lo & 0x3f)); - } else if (hi != 0 || lo >= 0x80) { - /* 2 bytes total */ - /* byte 0: 110HHHLL */ - /* byte 1: 10LLLLLL */ - *dst++ = (char)(0xc0 | - (hi << 2) | - ((lo >> 6) & 0x03)); - *dst++ = (char)(0x80 | (lo & 0x3f)); - } else - /* else 1 byte total */ - /* byte 0: 0LLLLLLL */ - *dst++ = (char)lo; + if (hi != 0) { + __wt_errx(NULL, "Unicode \"%6.6s\"" + " byte out of range in JSON", + src - 6); + return (EINVAL); + } + *dst++ = (char)lo; + break; + case 'f': + *dst++ = '\f'; + break; + case 'n': + *dst++ = '\n'; + break; + case 'r': + *dst++ = '\r'; + break; + case 't': + *dst++ = '\t'; + break; + case '"': + case '\\': + *dst++ = ch; + break; + WT_ILLEGAL_VALUE(session); } - else - *dst++ = *src; - } else - *dst++ = *src; - src++; + else + *dst++ = ch; } if (src != srcend) return (ENOMEM); |