)]}'
{
  "commit": "a5bb10fd5e74101e7c07da93e7c32bbe60f6173a",
  "tree": "abd52d3a55253bb7d2c58dbd1e58749030c18988",
  "parents": [
    "29198213c9163c1d552ee2bdbf78d2b09ccc98b8"
  ],
  "author": {
    "name": "Taylor Blau",
    "email": "me@ttaylorr.com",
    "time": "Thu Apr 06 14:07:58 2023 -0400"
  },
  "committer": {
    "name": "Johannes Schindelin",
    "email": "johannes.schindelin@gmx.de",
    "time": "Mon Apr 17 21:15:40 2023 +0200"
  },
  "message": "config: avoid fixed-sized buffer when renaming/deleting a section\n\nWhen renaming (or deleting) a section of configuration, Git uses the\nfunction `git_config_copy_or_rename_section_in_file()` to rewrite the\nconfiguration file after applying the rename or deletion to the given\nsection.\n\nTo do this, Git repeatedly calls `fgets()` to read the existing\nconfiguration data into a fixed size buffer.\n\nWhen the configuration value under `old_name` exceeds the size of the\nbuffer, we will call `fgets()` an additional time even if there is no\nnewline in the configuration file, since our read length is capped at\n`sizeof(buf)`.\n\nIf the first character of the buffer (after zero or more characters\nsatisfying `isspace()`) is a \u0027[\u0027, Git will incorrectly treat it as\nbeginning a new section when the original section is being removed. In\nother words, a configuration value satisfying this criteria can\nincorrectly be considered as a new secftion instead of a variable in the\noriginal section.\n\nAvoid this issue by using a variable-width buffer in the form of a\nstrbuf rather than a fixed-with region on the stack. A couple of small\npoints worth noting:\n\n  - Using a strbuf will cause us to allocate arbitrary sizes to match\n    the length of each line.  In practice, we don\u0027t expect any\n    reasonable configuration files to have lines that long, and a\n    bandaid will be introduced in a later patch to ensure that this is\n    the case.\n\n  - We are using strbuf_getwholeline() here instead of strbuf_getline()\n    in order to match `fgets()`\u0027s behavior of leaving the trailing LF\n    character on the buffer (as well as a trailing NUL).\n\n    This could be changed later, but using strbuf_getwholeline() changes\n    the least about this function\u0027s implementation, so it is picked as\n    the safest path.\n\n  - It is temping to want to replace the loop to skip over characters\n    matching isspace() at the beginning of the buffer with a convenience\n    function like `strbuf_ltrim()`. But this is the wrong approach for a\n    couple of reasons:\n\n    First, it involves a potentially large and expensive `memmove()`\n    which we would like to avoid. Second, and more importantly, we also\n    *do* want to preserve those spaces to avoid changing the output of\n    other sections.\n\nIn all, this patch is a minimal replacement of the fixed-width buffer in\n`git_config_copy_or_rename_section_in_file()` to instead use a `struct\nstrbuf`.\n\nReported-by: André Baptista \u003candre@ethiack.com\u003e\nReported-by: Vítor Pinho \u003cvitor@ethiack.com\u003e\nHelped-by: Patrick Steinhardt \u003cps@pks.im\u003e\nCo-authored-by: Johannes Schindelin \u003cJohannes.Schindelin@gmx.de\u003e\nSigned-off-by: Johannes Schindelin \u003cJohannes.Schindelin@gmx.de\u003e\nSigned-off-by: Taylor Blau \u003cme@ttaylorr.com\u003e\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "1137bd73aff07c77e9b73a0b4c1d193cd38d88de",
      "old_mode": 33188,
      "old_path": "config.c",
      "new_id": "524347676d0da03b76bbe74bebf7078cf7c0d368",
      "new_mode": 33188,
      "new_path": "config.c"
    },
    {
      "type": "modify",
      "old_id": "cd8f744160e8bae4421e589545bb9a4c54802e6a",
      "old_mode": 33261,
      "old_path": "t/t1300-config.sh",
      "new_id": "24c13b91dbd669773041032f8156126c8b337da2",
      "new_mode": 33261,
      "new_path": "t/t1300-config.sh"
    }
  ]
}
