|
21 | 21 |
|
22 | 22 | #include "util.h" // NOLINT(build/include_inline)
|
23 | 23 | #include <cmath>
|
| 24 | +#include <cstdint> |
24 | 25 | #include "util-inl.h"
|
25 | 26 |
|
26 | 27 | #include "debug_utils-inl.h"
|
|
31 | 32 | #include "node_snapshot_builder.h"
|
32 | 33 | #include "node_v8_platform-inl.h"
|
33 | 34 | #include "string_bytes.h"
|
34 |
| -#include "uv.h" |
35 | 35 | #include "v8-value.h"
|
36 | 36 |
|
37 | 37 | #ifdef _WIN32
|
|
56 | 56 |
|
57 | 57 | static std::atomic_int seq = {0}; // Sequence number for diagnostic filenames.
|
58 | 58 |
|
| 59 | +// F_OK etc. constants |
| 60 | +#ifdef _WIN32 |
| 61 | +#include "uv.h" |
| 62 | +#else |
| 63 | +#include <unistd.h> |
| 64 | +#endif |
| 65 | + |
| 66 | +// The access modes can be any of F_OK, R_OK, W_OK or X_OK. Some might not be |
| 67 | +// available on specific systems. They can be used in combination as well |
| 68 | +// (F_OK | R_OK | W_OK | X_OK). |
| 69 | +constexpr int kMaximumAccessMode = F_OK | W_OK | R_OK | X_OK; |
| 70 | +constexpr int kMinimumAccessMode = std::min({F_OK, W_OK, R_OK, X_OK}); |
| 71 | + |
| 72 | +constexpr int kDefaultCopyMode = 0; |
| 73 | +// The copy modes can be any of UV_FS_COPYFILE_EXCL, UV_FS_COPYFILE_FICLONE or |
| 74 | +// UV_FS_COPYFILE_FICLONE_FORCE. They can be used in combination as well |
| 75 | +// (US_FS_COPYFILE_EXCL | US_FS_COPYFILE_FICLONE | |
| 76 | +// US_FS_COPYFILE_FICLONE_FORCE). |
| 77 | +constexpr int kMinimumCopyMode = std::min({kDefaultCopyMode, |
| 78 | + UV_FS_COPYFILE_EXCL, |
| 79 | + UV_FS_COPYFILE_FICLONE, |
| 80 | + UV_FS_COPYFILE_FICLONE_FORCE}); |
| 81 | +constexpr int kMaximumCopyMode = |
| 82 | + UV_FS_COPYFILE_EXCL | UV_FS_COPYFILE_FICLONE | UV_FS_COPYFILE_FICLONE_FORCE; |
| 83 | + |
59 | 84 | namespace node {
|
60 | 85 |
|
61 | 86 | using v8::ArrayBuffer;
|
@@ -787,4 +812,49 @@ v8::Maybe<int32_t> GetValidatedFd(Environment* env,
|
787 | 812 | return v8::Just(static_cast<int32_t>(fd));
|
788 | 813 | }
|
789 | 814 |
|
| 815 | +v8::Maybe<int> GetValidFileMode(Environment* env, |
| 816 | + v8::Local<v8::Value> input, |
| 817 | + uv_fs_type type) { |
| 818 | + // Allow only int32 or null/undefined values. |
| 819 | + if (input->IsNumber()) { |
| 820 | + // We cast the input to v8::Number to avoid overflows. |
| 821 | + auto num = input.As<v8::Number>()->Value(); |
| 822 | + |
| 823 | + // Handle infinity and NaN values |
| 824 | + if (std::isinf(num) || std::isnan(num)) { |
| 825 | + THROW_ERR_OUT_OF_RANGE(env, "mode is out of range"); |
| 826 | + return v8::Nothing<int>(); |
| 827 | + } |
| 828 | + } else if (!input->IsNullOrUndefined()) { |
| 829 | + THROW_ERR_INVALID_ARG_TYPE(env, "mode must be int32 or null/undefined"); |
| 830 | + return v8::Nothing<int>(); |
| 831 | + } |
| 832 | + |
| 833 | + int min = kMinimumAccessMode; |
| 834 | + int max = kMaximumAccessMode; |
| 835 | + int def = F_OK; |
| 836 | + |
| 837 | + CHECK(type == UV_FS_ACCESS || type == UV_FS_COPYFILE); |
| 838 | + |
| 839 | + if (type == UV_FS_COPYFILE) { |
| 840 | + min = kMinimumCopyMode; |
| 841 | + max = kMaximumCopyMode; |
| 842 | + def = input->IsNullOrUndefined() ? kDefaultCopyMode |
| 843 | + : input.As<v8::Int32>()->Value(); |
| 844 | + } |
| 845 | + |
| 846 | + if (input->IsNullOrUndefined()) { |
| 847 | + return v8::Just(def); |
| 848 | + } |
| 849 | + |
| 850 | + const int mode = input.As<v8::Int32>()->Value(); |
| 851 | + if (mode < min || mode > max) { |
| 852 | + THROW_ERR_OUT_OF_RANGE( |
| 853 | + env, "mode is out of range: >= %d && <= %d", min, max); |
| 854 | + return v8::Nothing<int>(); |
| 855 | + } |
| 856 | + |
| 857 | + return v8::Just(mode); |
| 858 | +} |
| 859 | + |
790 | 860 | } // namespace node
|
0 commit comments