Skip to content

Instantly share code, notes, and snippets.

@xeioex
Created August 28, 2025 22:05
Show Gist options
  • Save xeioex/dc7839632d860dc6843469bddee2462b to your computer and use it in GitHub Desktop.
Save xeioex/dc7839632d860dc6843469bddee2462b to your computer and use it in GitHub Desktop.
diff --git a/nginx/ngx_http_js_module.c b/nginx/ngx_http_js_module.c
index 145c1955..32da434f 100644
--- a/nginx/ngx_http_js_module.c
+++ b/nginx/ngx_http_js_module.c
@@ -5905,12 +5905,14 @@ ngx_http_qjs_ext_subrequest(JSContext *cx, JSValueConst this_val,
"the primary request");
}
- if (ngx_qjs_string(cx, argv[0], &uri) != NGX_OK) {
- return JS_ThrowTypeError(cx, "failed to convert uri arg");
+ uri.data = (u_char *) JS_ToCStringLen(cx, &uri.len, argv[0]);
+ if (uri.data == NULL) {
+ return JS_EXCEPTION;
}
if (uri.len == 0) {
- return JS_ThrowTypeError(cx, "uri is empty");
+ JS_ThrowTypeError(cx, "uri is empty");
+ goto exception;
}
options = JS_UNDEFINED;
@@ -5931,8 +5933,9 @@ ngx_http_qjs_ext_subrequest(JSContext *cx, JSValueConst this_val,
arg = argv[1];
if (JS_IsString(arg)) {
- if (ngx_qjs_string(cx, arg, &args) != NGX_OK) {
- return JS_ThrowTypeError(cx, "failed to convert args");
+ args.data = (u_char *) JS_ToCStringLen(cx, &args.len, arg);
+ if (args.data == NULL) {
+ goto exception;
}
} else if (JS_IsFunction(cx, arg)) {
@@ -5942,27 +5945,27 @@ ngx_http_qjs_ext_subrequest(JSContext *cx, JSValueConst this_val,
options = arg;
} else if (!JS_IsNullOrUndefined(arg)) {
- return JS_ThrowTypeError(cx, "failed to convert args");
+ JS_ThrowTypeError(cx, "failed to convert args");
+ goto exception;
}
if (!JS_IsUndefined(options)) {
value = JS_GetPropertyStr(cx, options, "args");
if (JS_IsException(value)) {
- return JS_EXCEPTION;
+ goto exception;
}
if (!JS_IsUndefined(value)) {
- rc = ngx_qjs_string(cx, value, &args);
+ args.data = (u_char *) JS_ToCStringLen(cx, &args.len, value);
JS_FreeValue(cx, value);
-
- if (rc != NGX_OK) {
- return JS_ThrowTypeError(cx, "failed to convert options.args");
+ if (args.data == NULL) {
+ goto exception;
}
}
value = JS_GetPropertyStr(cx, options, "detached");
if (JS_IsException(value)) {
- return JS_EXCEPTION;
+ goto exception;
}
if (!JS_IsUndefined(value)) {
@@ -5972,15 +5975,14 @@ ngx_http_qjs_ext_subrequest(JSContext *cx, JSValueConst this_val,
value = JS_GetPropertyStr(cx, options, "method");
if (JS_IsException(value)) {
- return JS_EXCEPTION;
+ goto exception;
}
if (!JS_IsUndefined(value)) {
- rc = ngx_qjs_string(cx, value, &method_name);
+ method_name.data = JS_ToCStringLen(cx, &method_name.len, value);
JS_FreeValue(cx, value);
-
- if (rc != NGX_OK) {
- return JS_ThrowTypeError(cx, "failed to convert option.method");
+ if (method_name.data == NULL) {
+ goto exception;
}
while (method < methods_max) {
@@ -5999,15 +6001,17 @@ ngx_http_qjs_ext_subrequest(JSContext *cx, JSValueConst this_val,
value = JS_GetPropertyStr(cx, options, "body");
if (JS_IsException(value)) {
- return JS_EXCEPTION;
+ goto exception;
}
if (!JS_IsUndefined(value)) {
+ body_arg.data = (u_char *) JS_ToCStringLen(cx, &body_arg.len, value);
rc = ngx_qjs_string(cx, value, &body_arg);
JS_FreeValue(cx, value);
if (rc != NGX_OK) {
- return JS_ThrowTypeError(cx, "failed to convert option.body");
+ JS_ThrowTypeError(cx, "failed to convert option.body");
+ goto exception;
}
has_body = 1;
@@ -6017,22 +6021,25 @@ ngx_http_qjs_ext_subrequest(JSContext *cx, JSValueConst this_val,
flags = NGX_HTTP_LOG_UNSAFE;
if (ngx_http_parse_unsafe_uri(r, &uri, &args, &flags) != NGX_OK) {
- return JS_ThrowTypeError(cx, "unsafe uri");
+ JS_ThrowTypeError(cx, "unsafe uri");
+ goto exception;
}
arg = argv[2];
if (JS_IsUndefined(callback) && !JS_IsNullOrUndefined(arg)) {
if (!JS_IsFunction(cx, arg)) {
- return JS_ThrowTypeError(cx, "callback is not a function");
+ JS_ThrowTypeError(cx, "callback is not a function");
+ goto exception;
}
callback = arg;
}
if (detached && !JS_IsUndefined(callback)) {
- return JS_ThrowTypeError(cx, "detached flag and callback are mutually "
- "exclusive");
+ JS_ThrowTypeError(cx, "detached flag and callback are mutually "
+ "exclusive");
+ goto exception;
}
retval = JS_UNDEFINED;
@@ -6041,7 +6048,7 @@ ngx_http_qjs_ext_subrequest(JSContext *cx, JSValueConst this_val,
if (!detached) {
ps = ngx_palloc(r->pool, sizeof(ngx_http_post_subrequest_t));
if (ps == NULL) {
- return JS_ThrowOutOfMemory(cx);
+ goto memory_error;
}
promise = !!JS_IsUndefined(callback);
@@ -6049,7 +6056,7 @@ ngx_http_qjs_ext_subrequest(JSContext *cx, JSValueConst this_val,
event = ngx_pcalloc(r->pool, sizeof(ngx_qjs_event_t)
+ sizeof(JSValue) * 2);
if (event == NULL) {
- return JS_ThrowOutOfMemory(cx);
+ goto memory_error;
}
event->ctx = cx;
@@ -6060,7 +6067,7 @@ ngx_http_qjs_ext_subrequest(JSContext *cx, JSValueConst this_val,
if (promise) {
retval = JS_NewPromiseCapability(cx, &event->args[0]);
if (JS_IsException(retval)) {
- return JS_EXCEPTION;
+ goto exception;
}
callback = event->args[0];
@@ -6085,7 +6092,8 @@ ngx_http_qjs_ext_subrequest(JSContext *cx, JSValueConst this_val,
if (ngx_http_subrequest(r, &uri, args.len ? &args : NULL, &sr, ps, flags)
!= NGX_OK)
{
- return JS_ThrowInternalError(cx, "subrequest creation failed");
+ JS_ThrowInternalError(cx, "subrequest creation failed");
+ goto exception;
}
if (event != NULL) {
@@ -6134,11 +6142,22 @@ ngx_http_qjs_ext_subrequest(JSContext *cx, JSValueConst this_val,
sr->headers_in.chunked = 0;
}
+ JS_FreeCString(cx, (char *) uri.data);
+
return retval;
memory_error:
- return JS_ThrowOutOfMemory(cx);
+ JS_ThrowOutOfMemory(cx);
+
+ /* Fall through. */
+
+exception:
+
+ JS_FreeCString(cx, (char *) uri.data);
+
+ return JS_EXCEPTION;
+
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment