Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/bun.js/api/bun/socket/SocketAddress.zig
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ pub fn parse(global: *jsc.JSGlobalObject, callframe: *jsc.CallFrame) bun.JSError
};
defer url_str.deref();

const url = jsc.URL.fromString(url_str) orelse return .js_undefined;
const url = jsc.URL.fromString(url_str) catch return .js_undefined;
defer url.deinit();
const host = url.host();
const port_: u16 = blk: {
Expand Down
146 changes: 0 additions & 146 deletions src/bun.js/bindings/BunString.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -528,22 +528,6 @@ extern "C" [[ZIG_EXPORT(nothrow)]] void BunString__toWTFString(BunString* bunStr
bunString->tag = BunStringTag::WTFStringImpl;
}

extern "C" BunString URL__getFileURLString(BunString* filePath)
{
return Bun::toStringRef(WTF::URL::fileURLWithFileSystemPath(filePath->toWTFString()).stringWithoutFragmentIdentifier());
}

extern "C" size_t URL__originLength(const char* latin1_slice, size_t len)
{
WTF::String string = WTF::StringView(latin1_slice, len, true).toString();
if (!string)
return 0;
WTF::URL url(string);
if (!url.isValid())
return 0;
return url.pathStart();
}

extern "C" JSC::EncodedJSValue BunString__toJSDOMURL(JSC::JSGlobalObject* lexicalGlobalObject, BunString* bunString)
{
auto& globalObject = *jsCast<Zig::GlobalObject*>(lexicalGlobalObject);
Expand All @@ -559,136 +543,6 @@ extern "C" JSC::EncodedJSValue BunString__toJSDOMURL(JSC::JSGlobalObject* lexica
RELEASE_AND_RETURN(throwScope, JSC::JSValue::encode(jsValue));
}

extern "C" WTF::URL* URL__fromJS(EncodedJSValue encodedValue, JSC::JSGlobalObject* globalObject)
{
auto throwScope = DECLARE_THROW_SCOPE(globalObject->vm());
JSC::JSValue value = JSC::JSValue::decode(encodedValue);
auto str = value.toWTFString(globalObject);
RETURN_IF_EXCEPTION(throwScope, nullptr);
if (str.isEmpty()) {
return nullptr;
}

auto url = WTF::URL(str);
if (!url.isValid() || url.isNull())
return nullptr;

return new WTF::URL(WTFMove(url));
}

extern "C" BunString URL__getHrefFromJS(EncodedJSValue encodedValue, JSC::JSGlobalObject* globalObject)
{
auto throwScope = DECLARE_THROW_SCOPE(globalObject->vm());
JSC::JSValue value = JSC::JSValue::decode(encodedValue);
auto str = value.toWTFString(globalObject);
RETURN_IF_EXCEPTION(throwScope, { BunStringTag::Dead });
if (str.isEmpty()) {
return { BunStringTag::Dead };
}

auto url = WTF::URL(str);
if (!url.isValid() || url.isEmpty())
return { BunStringTag::Dead };

return Bun::toStringRef(url.string());
}

extern "C" BunString URL__getHref(BunString* input)
{
auto&& str = input->toWTFString();
auto url = WTF::URL(str);
if (!url.isValid() || url.isEmpty())
return { BunStringTag::Dead };

return Bun::toStringRef(url.string());
}

extern "C" BunString URL__pathFromFileURL(BunString* input)
{
auto&& str = input->toWTFString();
auto url = WTF::URL(str);
if (!url.isValid() || url.isEmpty())
return { BunStringTag::Dead };

return Bun::toStringRef(url.fileSystemPath());
}

extern "C" BunString URL__getHrefJoin(BunString* baseStr, BunString* relativeStr)
{
auto base = baseStr->toWTFString();
auto relative = relativeStr->toWTFString();
auto url = WTF::URL(WTF::URL(base), relative);
if (!url.isValid() || url.isEmpty())
return { BunStringTag::Dead };

return Bun::toStringRef(url.string());
}

extern "C" WTF::URL* URL__fromString(BunString* input)
{
auto&& str = input->toWTFString();
auto url = WTF::URL(str);
if (!url.isValid())
return nullptr;

return new WTF::URL(WTFMove(url));
}

extern "C" BunString URL__protocol(WTF::URL* url)
{
return Bun::toStringRef(url->protocol().toStringWithoutCopying());
}

extern "C" void URL__deinit(WTF::URL* url)
{
delete url;
}

extern "C" BunString URL__href(WTF::URL* url)
{
return Bun::toStringRef(url->string());
}

extern "C" BunString URL__username(WTF::URL* url)
{
return Bun::toStringRef(url->user());
}

extern "C" BunString URL__password(WTF::URL* url)
{
return Bun::toStringRef(url->password());
}

extern "C" BunString URL__search(WTF::URL* url)
{
return Bun::toStringRef(url->query().toStringWithoutCopying());
}

extern "C" BunString URL__host(WTF::URL* url)
{
return Bun::toStringRef(url->host().toStringWithoutCopying());
}
extern "C" BunString URL__hostname(WTF::URL* url)
{
return Bun::toStringRef(url->hostAndPort());
}

extern "C" uint32_t URL__port(WTF::URL* url)
{
auto port = url->port();

if (port.has_value()) {
return port.value();
}

return std::numeric_limits<uint32_t>::max();
}

extern "C" BunString URL__pathname(WTF::URL* url)
{
return Bun::toStringRef(url->path().toStringWithoutCopying());
}

size_t BunString::utf8ByteLength(const WTF::String& str)
{
if (str.isEmpty())
Expand Down
157 changes: 157 additions & 0 deletions src/bun.js/bindings/URL.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
#include "root.h"

#include "helpers.h"

using namespace JSC;

extern "C" BunString URL__getFileURLString(BunString* _Nonnull filePath)
{
return Bun::toStringRef(WTF::URL::fileURLWithFileSystemPath(filePath->toWTFString()).stringWithoutFragmentIdentifier());
}

extern "C" size_t URL__originLength(const char* latin1_slice, size_t len)
{
WTF::String string = WTF::StringView(latin1_slice, len, true).toString();
if (!string)
return 0;
WTF::URL url(string);
if (!url.isValid())
return 0;
return url.pathStart();
}
Comment thread
Jarred-Sumner marked this conversation as resolved.

extern "C" WTF::URL* URL__fromJS(EncodedJSValue encodedValue, JSC::JSGlobalObject* globalObject)
{
auto throwScope = DECLARE_THROW_SCOPE(globalObject->vm());
JSC::JSValue value = JSC::JSValue::decode(encodedValue);
auto str = value.toWTFString(globalObject);
RETURN_IF_EXCEPTION(throwScope, nullptr);
if (str.isEmpty()) {
return nullptr;
}

auto url = WTF::URL(str);
if (!url.isValid() || url.isNull())
return nullptr;

return new WTF::URL(WTFMove(url));
}

extern "C" BunString URL__getHrefFromJS(EncodedJSValue encodedValue, JSC::JSGlobalObject* globalObject)
{
auto throwScope = DECLARE_THROW_SCOPE(globalObject->vm());
JSC::JSValue value = JSC::JSValue::decode(encodedValue);
auto str = value.toWTFString(globalObject);
RETURN_IF_EXCEPTION(throwScope, { BunStringTag::Dead });
if (str.isEmpty()) {
return { BunStringTag::Dead };
}

auto url = WTF::URL(str);
if (!url.isValid() || url.isEmpty())
return { BunStringTag::Dead };

return Bun::toStringRef(url.string());
}

extern "C" BunString URL__getHref(BunString* _Nonnull input)
{
auto&& str = input->toWTFString();
auto url = WTF::URL(str);
if (!url.isValid() || url.isEmpty())
return { BunStringTag::Dead };

return Bun::toStringRef(url.string());
}

extern "C" BunString URL__pathFromFileURL(BunString* _Nonnull input)
{
auto&& str = input->toWTFString();
auto url = WTF::URL(str);
if (!url.isValid() || url.isEmpty())
return { BunStringTag::Dead };

return Bun::toStringRef(url.fileSystemPath());
}

extern "C" BunString URL__getHrefJoin(BunString* _Nonnull baseStr, BunString* _Nonnull relativeStr)
{
auto base = baseStr->transferToWTFString();
auto relative = relativeStr->transferToWTFString();
auto url = WTF::URL(WTF::URL(base), relative);
if (!url.isValid() || url.isEmpty())
return { BunStringTag::Dead };

return Bun::toStringRef(url.string());
}

extern "C" WTF::URL* URL__fromString(BunString* _Nonnull input)
{
auto&& str = input->toWTFString();
auto url = WTF::URL(str);
if (!url.isValid())
return nullptr;

return new WTF::URL(WTFMove(url));
}

extern "C" BunString URL__protocol(WTF::URL* _Nonnull url)
{
return Bun::toStringRef(url->protocol().toStringWithoutCopying());
}

extern "C" void URL__setProtocol(WTF::URL* url, BunString newProtocol)
{
String newProtocolStr = newProtocol.toWTFString(BunString::ZeroCopy);
url->setProtocol(newProtocolStr);
}
Comment on lines +103 to +107

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Add null check for url parameter.

The function dereferences url without checking for null, which can cause a crash.

Apply this diff to add a null check:

 extern "C" void URL__setProtocol(WTF::URL* url, BunString newProtocol)
 {
+    if (!url)
+        return;
     String newProtocolStr = newProtocol.toWTFString(BunString::ZeroCopy);
     url->setProtocol(newProtocolStr);
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
extern "C" void URL__setProtocol(WTF::URL* url, BunString newProtocol)
{
String newProtocolStr = newProtocol.toWTFString(BunString::ZeroCopy);
url->setProtocol(newProtocolStr);
}
extern "C" void URL__setProtocol(WTF::URL* url, BunString newProtocol)
{
if (!url)
return;
String newProtocolStr = newProtocol.toWTFString(BunString::ZeroCopy);
url->setProtocol(newProtocolStr);
}
🤖 Prompt for AI Agents
In src/bun.js/bindings/URL.cpp around lines 103 to 107, the function
URL__setProtocol dereferences the url parameter without checking for null;
update the function to validate url is non-null before using it and return early
if it is null (optionally logging or no-op), ensuring no further operations
occur on a null pointer and maintaining the existing behavior when url is valid.


extern "C" void URL__deinit(WTF::URL* _Nonnull url)
{
delete url;
}

extern "C" BunString URL__href(WTF::URL* _Nonnull url)
{
return Bun::toStringRef(url->string());
}

extern "C" BunString URL__username(WTF::URL* _Nonnull url)
{
return Bun::toStringRef(url->user());
}

extern "C" BunString URL__password(WTF::URL* _Nonnull url)
{
return Bun::toStringRef(url->password());
}

extern "C" BunString URL__search(WTF::URL* _Nonnull url)
{
return Bun::toStringRef(url->query().toStringWithoutCopying());
}

extern "C" BunString URL__host(WTF::URL* _Nonnull url)
{
return Bun::toStringRef(url->host().toStringWithoutCopying());
}
extern "C" BunString URL__hostname(WTF::URL* _Nonnull url)
{
return Bun::toStringRef(url->hostAndPort());
}

extern "C" uint32_t URL__port(WTF::URL* _Nonnull url)
{
auto port = url->port();

if (port.has_value()) {
return port.value();
}

return std::numeric_limits<uint32_t>::max();
}

extern "C" BunString URL__pathname(WTF::URL* _Nonnull url)
{
return Bun::toStringRef(url->path().toStringWithoutCopying());
}
19 changes: 12 additions & 7 deletions src/bun.js/bindings/URL.zig
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ pub const URL = opaque {
extern fn URL__fromJS(JSValue, *jsc.JSGlobalObject) ?*URL;
extern fn URL__fromString(*bun.String) ?*URL;
extern fn URL__protocol(*URL) String;
extern fn URL__setProtocol(*URL, new_protocol: String) void;
extern fn URL__href(*URL) String;
extern fn URL__username(*URL) String;
extern fn URL__password(*URL) String;
Expand All @@ -23,11 +24,9 @@ pub const URL = opaque {
return URL__getHref(&input);
}

pub fn join(base: bun.String, relative: bun.String) String {
pub fn join(base: *bun.String, relative: *bun.String) String {
jsc.markBinding(@src());
var base_str = base;
var relative_str = relative;
return URL__getHrefJoin(&base_str, &relative_str);
return URL__getHrefJoin(base, relative);
}

pub fn fileURLFromString(str: bun.String) String {
Expand Down Expand Up @@ -58,18 +57,24 @@ pub const URL = opaque {
return result;
}

pub fn fromUTF8(input: []const u8) ?*URL {
pub fn fromUTF8(input: []const u8) error{InvalidUrl}!*URL {
return fromString(String.borrowUTF8(input));
}
pub fn fromString(str: bun.String) ?*URL {
pub fn fromString(str: bun.String) error{InvalidUrl}!*URL {
jsc.markBinding(@src());
var input = str;
return URL__fromString(&input);
return URL__fromString(&input) orelse {
return error.InvalidUrl;
};
}
pub fn protocol(url: *URL) String {
jsc.markBinding(@src());
return URL__protocol(url);
}
pub fn setProtocol(url: *URL, new_protocol: String) void {
jsc.markBinding(@src());
URL__setProtocol(url, new_protocol);
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
pub fn href(url: *URL) String {
jsc.markBinding(@src());
return URL__href(url);
Expand Down
Loading