Repository: neovim/neovim
File: src/cjson/lua_cjson.c (C)

Code before:
                    strbuf_t b;
                    strbuf_init(&b, indent_len);
                    for (size_t i = 0; i < indent_len; i++)
                        strbuf_append_char_unsafe(&b, ' ');

                    options.pretty_indent = strbuf_free_to_string(&b, &indent_len);
                } else if (lua_isstring(l, -1)) {
                  options.pretty_indent = lua_tostring(l, -1);
                  if (!is_allowed_ws(options.pretty_indent))
                      luaL_error(l, "indent may only contain space, tab, LF, or CR");
                }
                lua_pop(l, 1);

                lua_getfield(l, -1, "item_separator");
                if (lua_isstring(l, -1)) {
                    options.pretty_item_separator = lua_tostring(l, -1);
                    if (!is_allowed_ws(options.pretty_item_separator))
                        luaL_error(l, "item_separator may only contain space, tab, LF, or CR");
                }
                lua_pop(l, 1);

                lua_getfield(l, -1, "key_separator");
                if (lua_isstring(l, -1)) {
                  options.pretty_key_separator = lua_tostring(l, -1);
                  if (!is_allowed_ws(options.pretty_key_separator))
                      luaL_error(l, "key_separator may only contain space, tab, LF, or CR");
                }
                lua_pop(l, 1);
            }
        }
        lua_pop(l, 2);
        break;
    default:
        return luaL_error (l, "expected 1 or 2 arguments");
    }

    if (!cfg->encode_keep_buffer) {
        /* Use private buffer */
        encode_buf = &local_encode_buf;
        strbuf_init(encode_buf, 0);
    } else {
        /* Reuse existing buffer */
        encode_buf = &cfg->encode_buf;
        strbuf_reset(encode_buf);
    }

    ctx.json = encode_buf;
    json_append_data(l, &ctx, 0);
    json = strbuf_string(encode_buf, &len);

    lua_pushlstring(l, json, len);

Review comment (suggestion):
```suggestion
                      luaL_error(l, "key_separator may only contain spaces, tabs, line feeds, or carriage returns");
```

Code after:
        utf8[1] = (codepoint & 0x3F) | 0x80;
        return 2;
    }

    /* 1110xxxx 10xxxxxx 10xxxxxx */
    if (codepoint <= 0xFFFF) {
        utf8[0] = (codepoint >> 12) | 0xE0;
        utf8[1] = ((codepoint >> 6) & 0x3F) | 0x80;
        utf8[2] = (codepoint & 0x3F) | 0x80;
        return 3;
    }

    /* 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */
    if (codepoint <= 0x1FFFFF) {
        utf8[0] = (codepoint >> 18) | 0xF0;
        utf8[1] = ((codepoint >> 12) & 0x3F) | 0x80;
        utf8[2] = ((codepoint >> 6) & 0x3F) | 0x80;
        utf8[3] = (codepoint & 0x3F) | 0x80;
        return 4;
    }

    return 0;
}


/* Called when index pointing to beginning of UTF-16 code escape: \uXXXX
 * \u is guaranteed to exist, but the remaining hex characters may be
 * missing.
 * Translate to UTF-8 and append to temporary token string.
 * Must advance index to the next character to be processed.
 * Returns: 0   success
 *          -1  error
 */
static int json_append_unicode_escape(json_parse_t *json)
{
    char utf8[4];       /* Surrogate pairs require 4 UTF-8 bytes */
    int codepoint;
    int surrogate_low;
    int len;
    int escape_len = 6;

    /* Fetch UTF-16 code unit */
    codepoint = decode_hex4(json->ptr + 2);
    if (codepoint < 0)
        return -1;

    /* UTF-16 surrogate pairs take the following 2 byte form:
     *      11011 x yyyyyyyyyy
     * When x = 0: y is the high 10 bits of the codepoint
     *      x = 1: y is the low 10 bits of the codepoint
     *