@@ -586,8 +586,84 @@ bool DatabaseSync::ShouldIgnoreSQLiteError() {
586586 return ignore_next_sqlite_error_;
587587}
588588
589- bool IsURL (Local<Value> value) {
590- return false ;
589+ bool IsURL (Environment* env, Local<Value> path) {
590+ Local<Object> url;
591+ if (!path->ToObject (env->context ()).ToLocal (&url)) {
592+ return false ;
593+ }
594+
595+ Local<Value> href;
596+ if (!url->Get (env->context (), FIXED_ONE_BYTE_STRING (env->isolate (), " href" ))
597+ .ToLocal (&href)) {
598+ return false ;
599+ }
600+
601+ if (!href->IsString ()) {
602+ return false ;
603+ }
604+
605+ return true ;
606+ }
607+
608+ Local<String> BufferToString (Environment* env, Local<Uint8Array> buffer) {
609+ size_t byteOffset = buffer->ByteOffset ();
610+ size_t byteLength = buffer->ByteLength ();
611+ if (byteLength == 0 ) {
612+ THROW_ERR_INVALID_ARG_TYPE (env->isolate (),
613+ " The \" path\" argument must not be empty." );
614+ return Local<String>();
615+ }
616+
617+ auto data =
618+ static_cast <const uint8_t *>(buffer->Buffer ()->Data ()) + byteOffset;
619+ if (std::find (data, data + byteLength, 0 ) != data + byteLength) {
620+ THROW_ERR_INVALID_ARG_TYPE (env->isolate (),
621+ " The \" path\" argument must not contain null "
622+ " bytes." );
623+ return Local<String>();
624+ }
625+
626+ auto path = std::string (reinterpret_cast <const char *>(data), byteLength);
627+ return String::NewFromUtf8 (
628+ env->isolate (), path.c_str (), NewStringType::kNormal )
629+ .ToLocalChecked ();
630+ }
631+
632+ Local<String> ToPathIfURL (Environment* env, Local<Value> path) {
633+ if (!IsURL (env, path)) {
634+ if (path->IsString ()) {
635+ return path.As <String>();
636+ }
637+
638+ return BufferToString (env, path.As <Uint8Array>());
639+ }
640+
641+ Local<Object> url = path.As <Object>();
642+ Local<Value> href;
643+ Local<Value> protocol;
644+ if (!url->Get (env->context (), FIXED_ONE_BYTE_STRING (env->isolate (), " href" ))
645+ .ToLocal (&href)) {
646+ return Local<String>();
647+ }
648+
649+ if (!url->Get (env->context (),
650+ FIXED_ONE_BYTE_STRING (env->isolate (), " protocol" ))
651+ .ToLocal (&protocol)) {
652+ return Local<String>();
653+ }
654+
655+ if (!href->IsString () || !protocol->IsString ()) {
656+ return Local<String>();
657+ }
658+
659+ std::string protocol_v =
660+ Utf8Value (env->isolate (), protocol.As <String>()).ToString ();
661+ if (protocol_v != " file:" ) {
662+ THROW_ERR_INVALID_URL_SCHEME (env->isolate ());
663+ return Local<String>();
664+ }
665+
666+ return href.As <String>();
591667}
592668
593669void DatabaseSync::New (const FunctionCallbackInfo<Value>& args) {
@@ -598,41 +674,21 @@ void DatabaseSync::New(const FunctionCallbackInfo<Value>& args) {
598674 return ;
599675 }
600676
601- Local<Value> path = args[0 ]; // if object, it's a URL, so path will be the
602- // "href" property then i can check the scheme
603- // and if it's not file, throw an error
604- if (!path->IsString () && !path->IsUint8Array () && !IsURL (path)) {
677+ Local<Value> path = args[0 ];
678+ if (!path->IsString () && !path->IsUint8Array () && !IsURL (env, path)) {
605679 THROW_ERR_INVALID_ARG_TYPE (env->isolate (),
606680 " The \" path\" argument must be a string, "
607681 " Uint8Array, or URL without null bytes." );
608682 return ;
609683 }
610684
611- std::string location;
612- if (path->IsUint8Array ()) {
613- Local<Uint8Array> buffer = path.As <Uint8Array>();
614- size_t byteOffset = buffer->ByteOffset ();
615- size_t byteLength = buffer->ByteLength ();
616- if (byteLength == 0 ) {
617- THROW_ERR_INVALID_ARG_TYPE (env->isolate (),
618- " The \" path\" argument must not be empty." );
619- return ;
620- }
621-
622- auto data =
623- static_cast <const uint8_t *>(buffer->Buffer ()->Data ()) + byteOffset;
624- if (std::find (data, data + byteLength, 0 ) != data + byteLength) {
625- THROW_ERR_INVALID_ARG_TYPE (env->isolate (),
626- " The \" path\" argument must not contain null "
627- " bytes." );
628- return ;
629- }
630-
631- location = std::string (reinterpret_cast <const char *>(data), byteLength);
632- } else {
633- location = Utf8Value (env->isolate (), args[0 ].As <String>()).ToString ();
685+ Local<String> path_str = ToPathIfURL (env, path);
686+ if (path_str.IsEmpty ()) {
687+ return ;
634688 }
635689
690+ std::string location = Utf8Value (env->isolate (), p).ToString ();
691+
636692 // TODO: uncomment this we still need to handle URLs
637693 /* auto parsed_url = ada::parse<ada::url_aggregator>(location, nullptr); */
638694 /* if (parsed_url && parsed_url->type != ada::scheme::FILE) { */
0 commit comments