)]}'
{
  "commit": "b1a48af7e8ee87cc46e1bbb07f81ac4853e0f27b",
  "tree": "0bf86225c84434471c89085173ddaf5978297beb",
  "parents": [
    "98d20fb23551a7ab900fcfe9d25fd9cb6a98a07f"
  ],
  "author": {
    "name": "Daniel Martí",
    "email": "mvdan@mvdan.cc",
    "time": "Tue Mar 31 12:20:15 2020 +0100"
  },
  "committer": {
    "name": "Daniel Martí",
    "email": "mvdan@mvdan.cc",
    "time": "Fri May 08 13:29:11 2020 +0000"
  },
  "message": "encoding/json: properly encode strings with \",string\" again\n\ngolang.org/cl/193604 fixed one bug when one encodes a string with the\n\",string\" option: if SetEscapeHTML(false) is used, we should not be\nusing HTML escaping for the inner string encoding. The CL correctly\nfixed that.\n\nThe CL also tried to speed up this edge case. By avoiding an entire new\ncall to Marshal, the new Issue34127 benchmark reduced its time/op by\n45%, and lowered the allocs/op from 3 to 2.\n\nHowever, that last optimization wasn\u0027t correct:\n\n\tSince Go 1.2 every string can be marshaled to JSON without error\n\teven if it contains invalid UTF-8 byte sequences. Therefore\n\tthere is no need to use Marshal again for the only reason of\n\tenclosing the string in double quotes.\n\nJSON string encoding isn\u0027t just about adding quotes and taking care of\ninvalid UTF-8. We also need to escape some characters, like tabs and\nnewlines.\n\nThe new code failed to do that. The bug resulted in the added test case\nfailing to roundtrip properly; before our fix here, we\u0027d see an error:\n\n\tinvalid use of ,string struct tag, trying to unmarshal \"\\\"\\b\\f\\n\\r\\t\\\"\\\\\\\"\" into string\n\nIf you pay close attention, you\u0027ll notice that the special characters\nlike tab and newline are only encoded once, not twice. When decoding\nwith the \",string\" option, the outer string decode works, but the inner\nstring decode fails, as we are now decoding a JSON string with unescaped\nspecial characters.\n\nThe fix we apply here isn\u0027t to go back to Marshal, as that would\nre-introduce the bug with SetEscapeHTML(false). Instead, we can use a\nnew encode state from the pool - it results in minimal performance\nimpact, and even reduces allocs/op further. The performance impact seems\nfair, given that we need to check the entire string for characters that\nneed to be escaped.\n\n\tname          old time/op    new time/op    delta\n\tIssue34127-8    89.7ns ± 2%   100.8ns ± 1%  +12.27%  (p\u003d0.000 n\u003d8+8)\n\n\tname          old alloc/op   new alloc/op   delta\n\tIssue34127-8     40.0B ± 0%     32.0B ± 0%  -20.00%  (p\u003d0.000 n\u003d8+8)\n\n\tname          old allocs/op  new allocs/op  delta\n\tIssue34127-8      2.00 ± 0%      1.00 ± 0%  -50.00%  (p\u003d0.000 n\u003d8+8)\n\nInstead of adding another standalone test, we convert an existing\n\"string tag\" test to be table-based, and add another test case there.\n\nOne test case from the original CL also had to be amended, due to the\nsame problem - when escaping \u0027\u003c\u0027 due to SetEscapeHTML(true), we need to\nend up with double escaping, since we\u0027re using \",string\".\n\nFixes #38173.\n\nChange-Id: I2b0df9e4f1d3452fff74fe910e189c930dde4b5b\nReviewed-on: https://go-review.googlesource.com/c/go/+/226498\nRun-TryBot: Daniel Martí \u003cmvdan@mvdan.cc\u003e\nTryBot-Result: Gobot Gobot \u003cgobot@golang.org\u003e\nReviewed-by: Joe Tsai \u003cthebrokentoaster@gmail.com\u003e\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "9c043593ce39772de5eeb722aeedd8ec2023fddd",
      "old_mode": 33188,
      "old_path": "src/encoding/json/encode.go",
      "new_id": "578d551102de47da3bc9f38b143f7d968f34c278",
      "new_mode": 33188,
      "new_path": "src/encoding/json/encode.go"
    },
    {
      "type": "modify",
      "old_id": "5110c7de9b123387aaf5cee9bb2e71b046c94276",
      "old_mode": 33188,
      "old_path": "src/encoding/json/encode_test.go",
      "new_id": "7290eca06f070769bf46225123ebde9c728294d6",
      "new_mode": 33188,
      "new_path": "src/encoding/json/encode_test.go"
    },
    {
      "type": "modify",
      "old_id": "ebb4f231d151892c981f495470825dee12f8cf57",
      "old_mode": 33188,
      "old_path": "src/encoding/json/stream_test.go",
      "new_id": "c9e5334337dff035de49c6621a5aa2ad9c6124b2",
      "new_mode": 33188,
      "new_path": "src/encoding/json/stream_test.go"
    }
  ]
}
