Skip to content
Merged
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
17 changes: 17 additions & 0 deletions R/visualizeNetworksWithHTML.R
Original file line number Diff line number Diff line change
Expand Up @@ -257,13 +257,19 @@ createEdgeElements <- function(edges) {
# Get styling for this edge
style <- getEdgeStyle(row$interaction, row$category, row$edge_type)

# Sanitize optional evidenceLink
evidence_link <- if ("evidenceLink" %in% names(row)) row$evidenceLink else NA_character_
evidence_link <- ifelse(is.na(evidence_link) | evidence_link == "NA", "", evidence_link)
evidence_link <- escape_js_string(evidence_link)

# Create edge data with styling information
edge_data <- paste0("{ data: { source: '", row$source,
"', target: '", row$target,
"', id: '", edge_key,
"', interaction: '", row$interaction,
"', edge_type: '", row$edge_type,
"', category: '", row$category,
"', evidenceLink: '", evidence_link,
"', color: '", style$color,
"', line_style: '", style$style,
"', arrow_shape: '", style$arrow,
Expand All @@ -275,6 +281,17 @@ createEdgeElements <- function(edges) {
return(edge_elements)
}

# Helper to safely embed strings into JS single-quoted literals
escape_js_string <- function(x) {
if (is.null(x)) return("")
x <- as.character(x)
x <- gsub("\\\\", "\\\\\\\\", x) # backslashes
x <- gsub("'", "\\\\'", x) # single quotes
x <- gsub("\r", "\\\\r", x)
x <- gsub("\n", "\\\\n", x)
x
}

Comment on lines +284 to +294
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Harden escaping against </script> termination and JS line-separator chars.

Current escaping doesn’t neutralize </script> or U+2028/U+2029, which can prematurely terminate the script tag or break JS parsing. Add these transformations.

 escape_js_string <- function(x) {
     if (is.null(x)) return("")
     x <- as.character(x)
     x <- gsub("\\\\", "\\\\\\\\", x)  # backslashes
     x <- gsub("'", "\\\\'", x)        # single quotes
     x <- gsub("\r", "\\\\r", x)
     x <- gsub("\n", "\\\\n", x)
+    # Prevent </script> tag breakouts and line-separator issues
+    x <- gsub("</", "<\\\\/", x, fixed = TRUE)
+    x <- gsub(intToUtf8(0x2028), "\\\\u2028", x, fixed = TRUE)
+    x <- gsub(intToUtf8(0x2029), "\\\\u2029", x, fixed = TRUE)
     x
 }
📝 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
# Helper to safely embed strings into JS single-quoted literals
escape_js_string <- function(x) {
if (is.null(x)) return("")
x <- as.character(x)
x <- gsub("\\\\", "\\\\\\\\", x) # backslashes
x <- gsub("'", "\\\\'", x) # single quotes
x <- gsub("\r", "\\\\r", x)
x <- gsub("\n", "\\\\n", x)
x
}
# Helper to safely embed strings into JS single-quoted literals
escape_js_string <- function(x) {
if (is.null(x)) return("")
x <- as.character(x)
x <- gsub("\\\\", "\\\\\\\\", x) # backslashes
x <- gsub("'", "\\\\'", x) # single quotes
x <- gsub("\r", "\\\\r", x)
x <- gsub("\n", "\\\\n", x)
# Prevent </script> tag breakouts and line-separator issues
x <- gsub("</", "<\\\\/", x, fixed = TRUE)
x <- gsub(intToUtf8(0x2028), "\\\\u2028", x, fixed = TRUE)
x <- gsub(intToUtf8(0x2029), "\\\\u2029", x, fixed = TRUE)
x
}
🤖 Prompt for AI Agents
In R/visualizeNetworksWithHTML.R around lines 284-294, the escape_js_string
helper must also neutralize occurrences of "</script>" and JS line-separator
characters U+2028 and U+2029; update the function to (after current
backslash/single-quote and CR/LF escapes) replace any case of "</script>" with
"<\\/script>" (or otherwise break the closing tag) and replace U+2028 and U+2029
characters with their escaped Unicode forms "\\u2028" and "\\u2029" so the
returned string cannot prematurely terminate the script tag or break JS parsing.

#' Generate Cytoscape visualization configuration
#'
#' This function creates a complete Cytoscape configuration object that can be
Expand Down