)]}'
{
  "commit": "5ee4e9512e9a99f97c4a3fad397034028b3457c2",
  "tree": "0be7e768538d0aea7482aad1a3b014ea1cc23e6e",
  "parents": [
    "a792f8804773f9c6c8fa55a8d9a502d56bd79b2b"
  ],
  "author": {
    "name": "David Benjamin",
    "email": "davidben@google.com",
    "time": "Wed Mar 06 16:48:35 2024 -0500"
  },
  "committer": {
    "name": "Boringssl LUCI CQ",
    "email": "boringssl-scoped@luci-project-accounts.iam.gserviceaccount.com",
    "time": "Mon Mar 11 21:55:10 2024 +0000"
  },
  "message": "Add BIO_FP_TEXT\n\nThis CL allows us to reduce the patch set on CPython.\n\nBIO_new_fp is the FILE* analog of BIO_new_fd. However, it behaves very\nstrangely w.r.t. Windows file translation modes. Instead of simply\ninheriting the FILE* as the caller constructed it, it unconditionally\noverrides the file\u0027s translation mode!\n\nThis is surprising. Moreover, if you change the mode without flushing\nthe file, weird things happen, as Windows documentation discusses:\nhttps://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/setmode?view\u003dmsvc-170\n\nThis leaks all the way up to calling code, because callers need to pass\na matching BIO_FP_TEXT to the FILE* they made. To be source-compatible\nwith such callers, notably CPython, we need to at least provide\nBIO_FP_TEXT.\n\nI first tried to fully match OpenSSL\u0027s semantics, but OpenSSL\u0027s\nsemantics are quite dangerous. Code tested on POSIX, calling\nBIO_new_fp(some_file, BIO_NOCLOSE), without much thought, is subtly\nbroken on Windows. It will change the mode of any file passed into it to\nbinary!\n\nOur own code runs into this. BIO_new_file internally calls BIO_new_fp.\nIn OpenSSL, they need to re-parse the mode string and figure out the\nright flag. ASN1_STRING_print_ex_fp doesn\u0027t even know which is the right\none. In OpenSSL, they actually call fwrite manually. We wrap it in a BIO\nand then use the BIO version, because it makes no sense to not use the\nabstraction we already have lying around. But that is incompatible with\nOpenSSL\u0027s semantics.\n\nSo instead I\u0027ve opted to make BIO_FP_TEXT switch the mode, but no flag\njust leaves the mode alone. This is slightly OpenSSL-incompatible\nbecause this code will work in OpenSSL, but continue to not work in\nBoringSSL:\n\n  // Oops, I actually wanted binary but forgot to use \"rb\"\n  FILE *f \u003d fopen(\"blah\", \"r\");\n  // But bio fixed it for me!\n  BIO *bio \u003d BIO_new_fp(f, BIO_NOCLOSE);\n\nBut callers should have passed \"rb\" if they wanted binary. This is also\npreexisting and no one has noticed. I think it\u0027s far more likely that\napplications *aren\u0027t* expecting BIO_new_fp to secretly change the input\nFILE\u0027s mode. If we ever need to, we can adopt OpenSSL\u0027s semantics and\nthen add BIO_FP_LEAVE_MY_FILE_ALONE. But those are worse defaults.\n\nChange-Id: I2905673c523eb24312c15d3000cbe34a66602700\nReviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/66809\nReviewed-by: Bob Beck \u003cbbe@google.com\u003e\nCommit-Queue: David Benjamin \u003cdavidben@google.com\u003e\nAuto-Submit: David Benjamin \u003cdavidben@google.com\u003e\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "d44c9dddfe3d75b14db3e94beca5d540e7f7839e",
      "old_mode": 33188,
      "old_path": "crypto/bio/bio_test.cc",
      "new_id": "075de0e957bac2b4908e4349d8abdfee0437615e",
      "new_mode": 33188,
      "new_path": "crypto/bio/bio_test.cc"
    },
    {
      "type": "modify",
      "old_id": "9b2a6ca0aa37166dff0c1aced308ed07635f4865",
      "old_mode": 33188,
      "old_path": "crypto/bio/file.c",
      "new_id": "e68a898c3f1b59abe3e08fe015966de938415765",
      "new_mode": 33188,
      "new_path": "crypto/bio/file.c"
    },
    {
      "type": "modify",
      "old_id": "93f3c0c1a97ee54ae5da303bdcfd4ff80da61476",
      "old_mode": 33188,
      "old_path": "include/openssl/bio.h",
      "new_id": "89cdc861c1e61a6315906fc28f739aac5bed6648",
      "new_mode": 33188,
      "new_path": "include/openssl/bio.h"
    }
  ]
}
