fix(utils): make isFormData detection logic stricter to avoid unnecessary calling of the `toString` method on the target;
Closes #5659
### Uploading large files fails with an exception

I'm using axios.put together with raw data to be uploaded to a server which doesn't accept multipart/form data. This works fine as long as the data to be uploaded is smaller than 512 MB. As soon as I try to use larger packages the axios.put fails with the following exception:

Node:buffer:798

return this.utf8Slice(0, this.length);
^
Error: Cannot create a string longer than 0x1fffffe8 characters
at Buffer.toString (node:buffer:798:17)
at Object.isFormData (file:///mytest/node_modules/axios/lib/utils.js:195:42)
at Object.transformRequest (file:///mytest/node_modules/axios/lib/defaults/index.js:55:30)
at transform (file:///mytest/node_modules/axios/lib/core/transformData.js:22:15)
at Object.forEach (file:///mytest/node_modules/axios/lib/utils.js:251:10)
at Object.transformData (file:///mytest/node_modules/axios/lib/core/transformData.js:21:9)
at Axios.dispatchRequest (file:///mytest/node_modules/axios/lib/core/dispatchRequest.js:40:31)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
code: 'ERR_STRING_TOO_LONG'

Why does axios try to interpret my request data as string even if Content-Type is set to "application/octet-stream"

### To Reproduce

      const buffer = fs.readFileSync(path);

      const config: AxiosRequestConfig = {
        url: url,
        method: options.method,
        headers: options.headers,
        data: buffer
      };

      const ax  = axios.create();
      ax.request(config).then(axiosResponse => {
        //do something with the response 
     })


### Code snippet

_No response_

### Expected behavior

_No response_

### Axios Version

1.3.5

### Adapter Version

_No response_

### Browser

_No response_

### Browser Version

_No response_

### Node.js Version

18.15.0

### OS

Windows 10 22H2

### Additional Library Versions

_No response_

### Additional context/Screenshots

_No response_
Uploading large files > 512 MB fails 
diff --git a/lib/utils.js b/lib/utils.js
index 6a388721c1..80ae34c0c4 100644
--- a/lib/utils.js
+++ b/lib/utils.js
@@ -188,12 +188,16 @@ const isStream = (val) => isObject(val) && isFunction(val.pipe);
  * @returns {boolean} True if value is an FormData, otherwise false
  */
 const isFormData = (thing) => {
-  const pattern = '[object FormData]';
+  let kind;
   return thing && (
-    (typeof FormData === 'function' && thing instanceof FormData) ||
-    toString.call(thing) === pattern ||
-    (isFunction(thing.toString) && thing.toString() === pattern)
-  );
+    (typeof FormData === 'function' && thing instanceof FormData) || (
+      isFunction(thing.append) && (
+        (kind = kindOf(thing)) === 'formdata' ||
+        // detect form-data instance
+        (kind === 'object' && isFunction(thing.toString) && thing.toString() === '[object FormData]')
+      )
+    )
+  )
 }
 
 /**

diff --git a/test/unit/utils/utils.js b/test/unit/utils/utils.js
index 73f378878b..8d40250318 100644
--- a/test/unit/utils/utils.js
+++ b/test/unit/utils/utils.js
@@ -22,6 +22,37 @@ describe('utils', function (){
       });
       assert.equal(utils.isFormData(new FormData()), true);
     });
+
+    it('should not call toString method on built-in objects instances', () => {
+      const buf = Buffer.from('123');
+
+      buf.toString = () => assert.fail('should not be called');
+
+      assert.equal(utils.isFormData(buf), false);
+    });
+
+    it('should not call toString method on built-in objects instances, even if append method exists', () => {
+      const buf = Buffer.from('123');
+
+      buf.append = () => {};
+
+      buf.toString = () => assert.fail('should not be called');
+
+      assert.equal(utils.isFormData(buf), false);
+    });
+
+    it('should detect custom FormData instances by toStringTag signature and append method presence', () => {
+      class FormData {
+        append(){
+
+        }
+
+        get [Symbol.toStringTag]() {
+          return 'FormData';
+        }
+      }
+      assert.equal(utils.isFormData(new FormData()), true);
+    });
   });
 
   describe('toJSON', function (){

{"should not call toString method on built-in objects instances, even if append method exists": {"run": "NONE", "test": "FAIL", "fix": "PASS"}, "should not call toString method on built-in objects instances": {"run": "NONE", "test": "FAIL", "fix": "PASS"}}
{"should support requesting data URL as a Blob (if supported by the environment)": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "should support beforeRedirect and proxy with redirect": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "should re-evaluate proxy on redirect when proxy set via env var": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "should support HTTP proxy auth": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "should support HTTPS proxy set via env var": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "should return true if the header has been deleted, otherwise false": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "should support requesting data URL as a Stream": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "should detect the FormData instance provided by the `form-data` package": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "should return buffer from data uri": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "should support array values": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "hostname and trailing colon in protocol": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "should properly handle synchronous errors inside the adapter": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "should use proxy for domains not in no_proxy": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "hostname and no trailing colon in protocol": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "should not fail with query parsing": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "should not use proxy for domains in no_proxy": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "should support headers argument": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "does not parse undefined": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "should convert to a plain object without circular references": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "should use objects with defined toJSON method without rebuilding": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "should pass errors for a failed stream": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "should delete the header": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "should validate Stream": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "should not rewrite the header if its value is false, unless rewrite options is set to true": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "should support proxy auth with header": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "should able to cancel multiple requests with CancelToken": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "should concatenate raw headers into an AxiosHeader instance": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "should support RegExp": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "should support HTTPS proxies": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "parses json": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "should return true if the header is defined, otherwise false": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "should be caseless": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "should support headers array": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "should not rewrite header the header if the value is false": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "should concatenate plain headers into an AxiosHeader instance": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "should support set accessor": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "should support gunzip error handling": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "should support max body length": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "ignores XML": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "should concatenate Axios headers into a new AxiosHeader instance": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "should support requesting data URL as a Buffer": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "should support requesting data URL as a String": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "should detect custom FormData instances by toStringTag signature and append method presence": {"run": "NONE", "test": "PASS", "fix": "PASS"}, "should validate Buffer": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "should return unsupported protocol": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "should support proxy auth from env": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "should return headers object with original headers case": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "should support function": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "should support string pattern": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "should display error while parsing params": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "should support adding a single header": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "should throw an error if the timeout property is not parsable as a number": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "should support HTTP proxies": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "should not pass through disabled proxy": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "should support get accessor": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "does not parse the empty string": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "should support proxy set via env var": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "should support adding multiple headers from raw headers string": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "should support auto-formatting": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "should support sockets": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "should return malformed URL": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "should support adding multiple headers": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "should clear all headers": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "should parse protocol part if it exists": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "obeys proxy settings when following redirects": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "should support has accessor": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "should clear matching headers if a matcher was specified": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "both hostname and host -> hostname takes precedence": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "should support external defined values": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "only host and https protocol": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "should serialize AxiosHeader instance to a raw headers string": {"run": "PASS", "test": "PASS", "fix": "PASS"}}
{"should not call toString method on built-in objects instances, even if append method exists": {"run": "NONE", "test": "FAIL", "fix": "PASS"}, "should not call toString method on built-in objects instances": {"run": "NONE", "test": "FAIL", "fix": "PASS"}}
{"passed_count": 70, "failed_count": 50, "skipped_count": 0, "passed_tests": ["should support requesting data URL as a Blob (if supported by the environment)", "should support beforeRedirect and proxy with redirect", "should re-evaluate proxy on redirect when proxy set via env var", "should support requesting data URL as a String", "should support HTTP proxy auth", "should validate Buffer", "should return unsupported protocol", "should support proxy auth from env", "should support HTTPS proxy set via env var", "should support requesting data URL as a Stream", "should return true if the header has been deleted, otherwise false", "should return headers object with original headers case", "should support function", "should support string pattern", "should display error while parsing params", "should support adding a single header", "should throw an error if the timeout property is not parsable as a number", "should return buffer from data uri", "should detect the FormData instance provided by the `form-data` package", "should support HTTP proxies", "should support array values", "hostname and trailing colon in protocol", "should properly handle synchronous errors inside the adapter", "should use proxy for domains not in no_proxy", "should not pass through disabled proxy", "hostname and no trailing colon in protocol", "should support get accessor", "does not parse the empty string", "should not fail with query parsing", "should not use proxy for domains in no_proxy", "should support headers argument", "does not parse undefined", "should convert to a plain object without circular references", "should support proxy set via env var", "should support adding multiple headers from raw headers string", "should pass errors for a failed stream", "should support auto-formatting", "should delete the header", "should use objects with defined toJSON method without rebuilding", "should validate Stream", "should support sockets", "should return malformed URL", "should support adding multiple headers", "should support proxy auth with header", "should able to cancel multiple requests with CancelToken", "should not rewrite the header if its value is false, unless rewrite options is set to true", "should clear all headers", "should concatenate raw headers into an AxiosHeader instance", "should parse protocol part if it exists", "obeys proxy settings when following redirects", "should support RegExp", "should support HTTPS proxies", "should support has accessor", "parses json", "should return true if the header is defined, otherwise false", "should clear matching headers if a matcher was specified", "should be caseless", "both hostname and host -> hostname takes precedence", "should not rewrite header the header if the value is false", "should support headers array", "should concatenate plain headers into an AxiosHeader instance", "should support set accessor", "should support gunzip error handling", "should support max body length", "should support external defined values", "ignores XML", "only host and https protocol", "should concatenate Axios headers into a new AxiosHeader instance", "should support requesting data URL as a Buffer", "should serialize AxiosHeader instance to a raw headers string"], "failed_tests": ["should not fail with an empty response with content-length header", "should parse the timeout property", "should post object data as url-encoded form if content-type is application/x-www-form-urlencoded", "should support decompression", "should properly support default max body length (follow-redirects as well)", "should support transparent gunzip", "should respect formSerializer config", "should support Blob", "should support download progress capturing", "issues", "should combine baseURL and url", "should be able to abort the response stream", "should allow passing JSON with BOM", "should support HTTP protocol", "should support max content length for redirected", "should support max redirects", "should preserve the HTTP verb on redirect", "should allow the User-Agent header to be overridden", "should support disabling automatic decompression of response data", "should respect the timeoutErrorMessage property", "should supply a user-agent if one is not specified", "should allow passing FormData", "should support buffers", "should support cancel", "should support download rate limit", "should support function as paramsSerializer value", "should not fail with chunked responses (without Content-Length header)", "should properly serialize nested objects for parsing with multer.js (express.js)", "should support basic auth", "should support upload progress capturing", "should support basic auth with a header", "should respect the timeout property", "supports http with nodejs", "should throw an error if http server that aborts a chunked request", "should provides a default User-Agent header", "should support beforeRedirect", "should support HTTPS protocol", "should not fail if response content-length header is missing", "should not redirect", "should handle set-cookie headers as an array", "should support UTF8", "should support streams", "should allow the Content-Length header to be overridden", "should redirect", "should support upload rate limit", "should support max content length", "should destroy the response stream with an error on request stream destroying", "should allow passing JSON", "should omit a user-agent if one is explicitly disclaimed", "should not fail with an empty response without content-length header"], "skipped_tests": []}
{"passed_count": 71, "failed_count": 53, "skipped_count": 0, "passed_tests": ["should support requesting data URL as a Blob (if supported by the environment)", "should support beforeRedirect and proxy with redirect", "should re-evaluate proxy on redirect when proxy set via env var", "should support requesting data URL as a String", "should detect custom FormData instances by toStringTag signature and append method presence", "should support HTTP proxy auth", "should validate Buffer", "should return unsupported protocol", "should support proxy auth from env", "should support HTTPS proxy set via env var", "should support requesting data URL as a Stream", "should return true if the header has been deleted, otherwise false", "should return headers object with original headers case", "should support function", "should support string pattern", "should display error while parsing params", "should support adding a single header", "should throw an error if the timeout property is not parsable as a number", "should return buffer from data uri", "should detect the FormData instance provided by the `form-data` package", "should support HTTP proxies", "should support array values", "hostname and trailing colon in protocol", "should properly handle synchronous errors inside the adapter", "should use proxy for domains not in no_proxy", "should not pass through disabled proxy", "hostname and no trailing colon in protocol", "should support get accessor", "does not parse the empty string", "should not fail with query parsing", "should not use proxy for domains in no_proxy", "should support headers argument", "does not parse undefined", "should convert to a plain object without circular references", "should support proxy set via env var", "should support adding multiple headers from raw headers string", "should pass errors for a failed stream", "should support auto-formatting", "should delete the header", "should use objects with defined toJSON method without rebuilding", "should validate Stream", "should support sockets", "should return malformed URL", "should support adding multiple headers", "should support proxy auth with header", "should able to cancel multiple requests with CancelToken", "should not rewrite the header if its value is false, unless rewrite options is set to true", "should clear all headers", "should concatenate raw headers into an AxiosHeader instance", "should parse protocol part if it exists", "obeys proxy settings when following redirects", "should support RegExp", "should support HTTPS proxies", "should support has accessor", "parses json", "should return true if the header is defined, otherwise false", "should clear matching headers if a matcher was specified", "should be caseless", "both hostname and host -> hostname takes precedence", "should not rewrite header the header if the value is false", "should support headers array", "should concatenate plain headers into an AxiosHeader instance", "should support set accessor", "should support gunzip error handling", "should support max body length", "should support external defined values", "ignores XML", "only host and https protocol", "should concatenate Axios headers into a new AxiosHeader instance", "should support requesting data URL as a Buffer", "should serialize AxiosHeader instance to a raw headers string"], "failed_tests": ["should not fail with an empty response with content-length header", "should parse the timeout property", "should post object data as url-encoded form if content-type is application/x-www-form-urlencoded", "should support decompression", "should properly support default max body length (follow-redirects as well)", "should support transparent gunzip", "should respect formSerializer config", "should support Blob", "should support download progress capturing", "issues", "should combine baseURL and url", "should be able to abort the response stream", "should allow passing JSON with BOM", "should support HTTP protocol", "should support max content length for redirected", "should not call toString method on built-in objects instances, even if append method exists", "should support max redirects", "should preserve the HTTP verb on redirect", "should allow the User-Agent header to be overridden", "should support disabling automatic decompression of response data", "should respect the timeoutErrorMessage property", "should supply a user-agent if one is not specified", "should allow passing FormData", "should support buffers", "should support cancel", "should support download rate limit", "should support function as paramsSerializer value", "should not fail with chunked responses (without Content-Length header)", "should properly serialize nested objects for parsing with multer.js (express.js)", "should support basic auth", "should support upload progress capturing", "should support basic auth with a header", "should respect the timeout property", "supports http with nodejs", "should throw an error if http server that aborts a chunked request", "utils", "should provides a default User-Agent header", "should support beforeRedirect", "should support HTTPS protocol", "should not fail if response content-length header is missing", "should not call toString method on built-in objects instances", "should not redirect", "should handle set-cookie headers as an array", "should support UTF8", "should support streams", "should allow the Content-Length header to be overridden", "should redirect", "should support upload rate limit", "should support max content length", "should destroy the response stream with an error on request stream destroying", "should allow passing JSON", "should omit a user-agent if one is explicitly disclaimed", "should not fail with an empty response without content-length header"], "skipped_tests": []}
{"passed_count": 73, "failed_count": 50, "skipped_count": 0, "passed_tests": ["should support requesting data URL as a Blob (if supported by the environment)", "should support beforeRedirect and proxy with redirect", "should re-evaluate proxy on redirect when proxy set via env var", "should support requesting data URL as a String", "should detect custom FormData instances by toStringTag signature and append method presence", "should support HTTP proxy auth", "should validate Buffer", "should return unsupported protocol", "should support proxy auth from env", "should support HTTPS proxy set via env var", "should support requesting data URL as a Stream", "should return true if the header has been deleted, otherwise false", "should return headers object with original headers case", "should support function", "should support string pattern", "should display error while parsing params", "should support adding a single header", "should throw an error if the timeout property is not parsable as a number", "should return buffer from data uri", "should detect the FormData instance provided by the `form-data` package", "should not call toString method on built-in objects instances, even if append method exists", "should support HTTP proxies", "should support array values", "hostname and trailing colon in protocol", "should properly handle synchronous errors inside the adapter", "should use proxy for domains not in no_proxy", "should not pass through disabled proxy", "hostname and no trailing colon in protocol", "should support get accessor", "does not parse the empty string", "should not fail with query parsing", "should not use proxy for domains in no_proxy", "should support headers argument", "does not parse undefined", "should convert to a plain object without circular references", "should support proxy set via env var", "should support adding multiple headers from raw headers string", "should pass errors for a failed stream", "should support auto-formatting", "should delete the header", "should use objects with defined toJSON method without rebuilding", "should validate Stream", "should support sockets", "should return malformed URL", "should support adding multiple headers", "should support proxy auth with header", "should able to cancel multiple requests with CancelToken", "should not rewrite the header if its value is false, unless rewrite options is set to true", "should clear all headers", "should concatenate raw headers into an AxiosHeader instance", "should parse protocol part if it exists", "obeys proxy settings when following redirects", "should support RegExp", "should support HTTPS proxies", "should support has accessor", "parses json", "should return true if the header is defined, otherwise false", "should clear matching headers if a matcher was specified", "should be caseless", "both hostname and host -> hostname takes precedence", "should not rewrite header the header if the value is false", "should support headers array", "should not call toString method on built-in objects instances", "should concatenate plain headers into an AxiosHeader instance", "should support set accessor", "should support gunzip error handling", "should support max body length", "should support external defined values", "ignores XML", "only host and https protocol", "should concatenate Axios headers into a new AxiosHeader instance", "should support requesting data URL as a Buffer", "should serialize AxiosHeader instance to a raw headers string"], "failed_tests": ["should not fail with an empty response with content-length header", "should parse the timeout property", "should post object data as url-encoded form if content-type is application/x-www-form-urlencoded", "should support decompression", "should properly support default max body length (follow-redirects as well)", "should support transparent gunzip", "should respect formSerializer config", "should support Blob", "should support download progress capturing", "issues", "should combine baseURL and url", "should be able to abort the response stream", "should allow passing JSON with BOM", "should support HTTP protocol", "should support max content length for redirected", "should support max redirects", "should preserve the HTTP verb on redirect", "should allow the User-Agent header to be overridden", "should support disabling automatic decompression of response data", "should respect the timeoutErrorMessage property", "should supply a user-agent if one is not specified", "should allow passing FormData", "should support buffers", "should support cancel", "should support download rate limit", "should support function as paramsSerializer value", "should not fail with chunked responses (without Content-Length header)", "should properly serialize nested objects for parsing with multer.js (express.js)", "should support basic auth", "should support upload progress capturing", "should support basic auth with a header", "should respect the timeout property", "supports http with nodejs", "should throw an error if http server that aborts a chunked request", "should provides a default User-Agent header", "should support beforeRedirect", "should support HTTPS protocol", "should not fail if response content-length header is missing", "should not redirect", "should handle set-cookie headers as an array", "should support UTF8", "should support streams", "should allow the Content-Length header to be overridden", "should redirect", "should support upload rate limit", "should support max content length", "should destroy the response stream with an error on request stream destroying", "should allow passing JSON", "should omit a user-agent if one is explicitly disclaimed", "should not fail with an empty response without content-length header"], "skipped_tests": []}