|
5 | 5 | #include "path.h" |
6 | 6 | #include "permission/permission.h" |
7 | 7 | #include "stream_base-inl.h" |
| 8 | +#include "string_bytes.h" |
8 | 9 | #include "util-inl.h" |
9 | 10 |
|
10 | 11 | // Copied from https://github.com/nodejs/node/blob/b07dc4d19fdbc15b4f76557dc45b3ce3a43ad0c3/src/util.cc#L36-L41. |
@@ -448,30 +449,60 @@ void CreateHeapSnapshotStream(const FunctionCallbackInfo<Value>& args) { |
448 | 449 | void TriggerHeapSnapshot(const FunctionCallbackInfo<Value>& args) { |
449 | 450 | Environment* env = Environment::GetCurrent(args); |
450 | 451 | Isolate* isolate = args.GetIsolate(); |
451 | | - CHECK_EQ(args.Length(), 2); |
| 452 | + CHECK_EQ(args.Length(), 4); |
452 | 453 | Local<Value> filename_v = args[0]; |
453 | 454 | auto options = GetHeapSnapshotOptions(args[1]); |
| 455 | + bool has_path = !args[2]->IsUndefined() && !args[2]->IsNull(); |
| 456 | + std::string final_filename; |
| 457 | + BufferValue path_v(isolate, args[2]); |
| 458 | + ToNamespacedPath(env, &path_v); |
| 459 | + |
| 460 | + const enum encoding encoding = ParseEncoding(isolate, args[3], UTF8); |
454 | 461 |
|
455 | 462 | if (filename_v->IsUndefined()) { |
456 | 463 | DiagnosticFilename name(env, "Heap", "heapsnapshot"); |
457 | | - THROW_IF_INSUFFICIENT_PERMISSIONS( |
458 | | - env, |
459 | | - permission::PermissionScope::kFileSystemWrite, |
460 | | - Environment::GetCwd(env->exec_path())); |
461 | | - if (WriteSnapshot(env, *name, options).IsNothing()) return; |
462 | | - if (String::NewFromUtf8(isolate, *name).ToLocal(&filename_v)) { |
463 | | - args.GetReturnValue().Set(filename_v); |
| 464 | + if (!has_path) { |
| 465 | + THROW_IF_INSUFFICIENT_PERMISSIONS( |
| 466 | + env, |
| 467 | + permission::PermissionScope::kFileSystemWrite, |
| 468 | + Environment::GetCwd(env->exec_path())); |
| 469 | + final_filename = *name; |
| 470 | + } else { |
| 471 | + THROW_IF_INSUFFICIENT_PERMISSIONS( |
| 472 | + env, |
| 473 | + permission::PermissionScope::kFileSystemWrite, |
| 474 | + path_v.ToStringView()); |
| 475 | + final_filename = path_v.ToString() + "/" + |
| 476 | + *name; // NOLINT(readability/pointer_notation) |
| 477 | + } |
| 478 | + } else { |
| 479 | + BufferValue filename(isolate, filename_v); |
| 480 | + CHECK_NOT_NULL(*filename); |
| 481 | + |
| 482 | + if (has_path) { |
| 483 | + final_filename = path_v.ToString() + "/" + filename.ToString(); |
| 484 | + THROW_IF_INSUFFICIENT_PERMISSIONS( |
| 485 | + env, permission::PermissionScope::kFileSystemWrite, final_filename); |
| 486 | + } else { |
| 487 | + ToNamespacedPath(env, &filename); |
| 488 | + THROW_IF_INSUFFICIENT_PERMISSIONS( |
| 489 | + env, |
| 490 | + permission::PermissionScope::kFileSystemWrite, |
| 491 | + filename.ToStringView()); |
| 492 | + final_filename = filename.ToString(); |
464 | 493 | } |
| 494 | + } |
| 495 | + |
| 496 | + // If encoding fails, snapshot is not triggered. |
| 497 | + Local<Value> ret; |
| 498 | + if (!StringBytes::Encode(isolate, final_filename.c_str(), encoding) |
| 499 | + .ToLocal(&ret)) { |
465 | 500 | return; |
466 | 501 | } |
467 | 502 |
|
468 | | - BufferValue path(isolate, filename_v); |
469 | | - CHECK_NOT_NULL(*path); |
470 | | - ToNamespacedPath(env, &path); |
471 | | - THROW_IF_INSUFFICIENT_PERMISSIONS( |
472 | | - env, permission::PermissionScope::kFileSystemWrite, path.ToStringView()); |
473 | | - if (WriteSnapshot(env, *path, options).IsNothing()) return; |
474 | | - return args.GetReturnValue().Set(filename_v); |
| 503 | + if (WriteSnapshot(env, final_filename.c_str(), options).IsNothing()) return; |
| 504 | + |
| 505 | + args.GetReturnValue().Set(ret); |
475 | 506 | } |
476 | 507 |
|
477 | 508 | void Initialize(Local<Object> target, |
|
0 commit comments