| 
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