@@ -168,7 +168,9 @@ fn waitNetworkIdleStep(session: *Session) !bool {
168168fn waitUrlContainsStep (session : * Session , needle : []const u8 ) ! bool {
169169 const payload = try evaluateForWait (session , "location.href" );
170170 defer session .allocator .free (payload );
171- return strings .containsIgnoreCase (payload , needle );
171+ const url = try extractEvaluationString (session .allocator , payload );
172+ defer session .allocator .free (url );
173+ return strings .containsIgnoreCase (url , needle );
172174}
173175
174176fn waitCookieStep (session : * Session , query : types.CookieQuery ) ! bool {
@@ -274,16 +276,21 @@ fn maybeEmitChallengeSignals(session: *Session) !void {
274276 if (! session .supports (.js_eval )) return ;
275277 const title_payload = try evaluateForWait (session , "document.title" );
276278 defer session .allocator .free (title_payload );
279+ const title = try extractEvaluationString (session .allocator , title_payload );
280+ defer session .allocator .free (title );
277281
278- const looks_like_challenge = strings .containsIgnoreCase (title_payload , "challenge" ) or
279- strings .containsIgnoreCase (title_payload , "just a moment" ) or
280- strings .containsIgnoreCase (title_payload , "attention required" ) or
281- strings .containsIgnoreCase (title_payload , "cf-chl" ) or
282- strings .containsIgnoreCase (title_payload , "cloudflare" );
282+ const looks_like_challenge = strings .containsIgnoreCase (title , "challenge" ) or
283+ strings .containsIgnoreCase (title , "just a moment" ) or
284+ strings .containsIgnoreCase (title , "attention required" ) or
285+ strings .containsIgnoreCase (title , "cf-chl" ) or
286+ strings .containsIgnoreCase (title , "cloudflare" );
283287
284288 const current_url = try currentUrl (session );
285289 defer session .allocator .free (current_url );
286290
291+ session .challenge_lock .lock ();
292+ defer session .challenge_lock .unlock ();
293+
287294 if (looks_like_challenge and ! session .challenge_active ) {
288295 session .challenge_active = true ;
289296 events .emit (session , .{
@@ -306,14 +313,27 @@ fn maybeEmitChallengeSignals(session: *Session) !void {
306313fn currentUrl (session : * Session ) ! []u8 {
307314 if (session .supports (.js_eval )) {
308315 const payload = try evaluateForWait (session , "location.href" );
309- return payload ;
316+ defer session .allocator .free (payload );
317+ return extractEvaluationString (session .allocator , payload );
310318 }
311319 session .state_lock .lock ();
312320 defer session .state_lock .unlock ();
313321 if (session .current_url ) | url | return session .allocator .dupe (u8 , url );
314322 return session .allocator .dupe (u8 , "" );
315323}
316324
325+ fn extractEvaluationString (allocator : std.mem.Allocator , payload : []const u8 ) ! []u8 {
326+ var parsed = std .json .parseFromSlice (std .json .Value , allocator , payload , .{}) catch {
327+ return allocator .dupe (u8 , payload );
328+ };
329+ defer parsed .deinit ();
330+ const value = extractEvaluationValue (parsed .value ) orelse return allocator .dupe (u8 , payload );
331+ return switch (value ) {
332+ .string = > allocator .dupe (u8 , value .string ),
333+ else = > std .json .Stringify .valueAlloc (allocator , value , .{}),
334+ };
335+ }
336+
317337fn clampTimeout (poll_interval_ms : u32 ) u32 {
318338 if (poll_interval_ms < 25 ) return 25 ;
319339 if (poll_interval_ms > 500 ) return 500 ;
0 commit comments