# # # encoding utilities # # # # option_info_to_json_type() # encode_json() # add_json() # close_json() # # string_to_html() # html_to_html() # get_formatted_html_column_value() # # # # # # # # # option_info_to_json_type() # # # subroutine(option_info_to_json_type( string option_info_type), ( # This converts an option_info type to the type used in JSON (add_json()). # I.e., "integer" is converted to "int", etc. string json_type; if (option_info_type eq "boolean" or option_info_type eq "bool") then ( json_type = "bool"; ) else if (option_info_type eq "integer" or option_info_type eq "int") then ( json_type = "int"; ) else if (option_info_type eq "float") then ( json_type = "float"; ) else if (option_info_type eq "bytes") then ( # bytes become "int" because the byte unit becomes separated from the number. json_type = "int"; ) else ( # Everything else is string, i.e. "string", "charset", "permissions", "", etc. json_type = "string"; ); # Return json_type; )); # # # # encode_json() # # # subroutine(encode_json(string s), ( if (matches_regular_expression(s, "[\\'\"\$()=%\s]")) then ( s = replace_all(s, "\\", "\u005C"); s = replace_all(s, "'", "\u0027"); s = replace_all(s, '"', "\u0022"); s = replace_all(s, "$", "\u0024"); # KHP 20/Aug/2010 escape bracses to avoid execution of javascript expressions s = replace_all(s, "(", "\u0028"); s = replace_all(s, ")", "\u0029"); # We escape any expression brace to make sure that the value does not become expanded upon display. # We make that simpler by escaping the equal sign only! s = replace_all(s, '=', "\u003d"); # handle %0 (Null) value or other none escaped values s = replace_all(s, "%0", "\u00250"); s = replace_all(s, "\0", "\u0000"); s = replace_all(s, "\t", "\u0009"); s = replace_all(s, "\n", "\u000A"); s = replace_all(s, "\v", "\u000B"); s = replace_all(s, "\f", "\u000C"); s = replace_all(s, "\r", "\u000D"); # debug_message("#### encoded json string: " . s . "\n"); ); s; )); # # # # add_json() # # # subroutine(add_json( string item_name, string item_value, string type), ( # This adds a JSON property name and value. # type is: string, int, float, bool or obj # For security reasons we also encode int, float and bool. Item values of type obj # are already encoded, they must not be encoded again! if (type eq "string") then ( # string '"' . item_name . '":"' . encode_json(item_value) . '",'; ) else if (type ne "obj") then ( # int, float or bool # Encode for security reasons # KHP 01/Jun/2011 - be more tolerate with empty values # by defining a default, otherwise we have an invalid # JSON string if (item_value eq "") then ( if (type eq "bool") then ( item_value = "false"; ) else ( item_value = "0"; ); ); '"' . item_name . '":' . encode_json(item_value) . ','; ) else ( # This is an object, don't encode '"' . item_name . '":' . item_value . ','; ); )); # # # # close_json() # # # subroutine(close_json(string s), ( # replaces the last comma of add_json() wih a curved brace s = replace_last(s, ",", "}"); s; )); # # # # string_to_html() # # # subroutine(string_to_html(string s), ( if (matches_regular_expression(s, "[&<>\"'()=\$\\%]")) then ( s = replace_all(s, "&", "&"); s = replace_all(s, "<", "<"); s = replace_all(s, ">", ">"); s = replace_all(s, '"', """); s = replace_all(s, "'", "'"); s = replace_all(s, "(", "("); s = replace_all(s, ")", ")"); s = replace_all(s, "=", "="); # We escape "=" so that we don't get any executable code in curley braces! s = replace_all(s, "$", "$"); # We escape any expression brace to make sure that the value does not become expanded upon display. # We already escape the equal character, so we don't need to replace the curly braces!s # s = replace_all(s, '{', "{"); # s = replace_all(s, '}', "}"); # s = replace_all(s, "\\", "\"); # Escpace backslash so that they don't escape anything upon -dp # handle %0 (Null) value or other none escaped values s = replace_all(s, "%0", "%0"); # Make sure there is no more % character followed by hex numbers s = replace_all(s, "%", "%"); ); s; )); # # # # html_to_html() # # # subroutine(html_to_html(string s), ( # This converts a string which may already contain HTML elements to HTML display, # this means we only escape critical characters such as "$". # This is used for example in headers and footers where users define custom HTML elements. # debug_message("#### html_to_html() s ori: " . s . "\n"); if (matches_regular_expression(s, "[\$%]")) then ( s = replace_all(s, "$", "$"); # handle %0 (Null) value or other none escaped values s = replace_all(s, "%0", "%0"); ); # debug_message("#### html_to_html() s escaped: " . s . "\n"); s; )); # # # # get_formatted_html_column_value() # # # # Applies text formatting (breaks and truncates text) # and escapes HTML markup and Salang code. # # Note, % escapes are displayed as such since version 8, # i.e. %20 in the query result is displayed as %20 in the table. # # To return a string in full length define: # max_text_length: 0 # max_continuous_text_length: 0 # max_continuous_text_length_offset: 0 subroutine(get_formatted_html_column_value( string column_value, string display_format_type, node text_info), ( int max_text_length = @text_info{"maximum_text_length"}; int max_continuous_text_length = @text_info{"maximum_continuous_text_length"}; int max_continuous_text_length_offset = @text_info{"maximum_continuous_text_length_offset"}; bool dash_breaks = @text_info{"dash_breaks"}; string break_entity = @text_info{"break_entity"}; # debug_message("\n\n#### get_formatted_html_column_value START \n\n"); # debug_message("\n#### Column value ori: " . replace_all(column_value, "$", "__ESCAPED_DOLLAR_IN_DEBUG_MESSAGE__") . "\n"); # # # Format the column value # # if (display_format_type ne "") then ( column_value = format(column_value, display_format_type); ); # # # Truncate string # # if (max_text_length > 0) then ( int string_length = length(column_value); if (string_length > max_text_length) then ( # debug_message("#### Truncate string is active\n"); column_value = substr(column_value, 0, max_text_length); column_value .= "..."; ); ); # # # Break string # # # A string in a html table will automatically break if the string # conatins a space or dash. Note, a dash breaks in IE, Safari and Opera, # it does not break in Mozilla or might not break in other browsers. # As Mozilla is a minor browser start using the dash for breaks from now # and imoplement web browser specific breaking later, i.e. break with # spaces for Mozilla and Netscape web browsers only. subroutine(break_string( string ori_string, int string_length, int max_continuous_text_length, int max_continuous_text_length_offset), ( int number_of_substrings = (string_length / max_continuous_text_length); if ((string_length % max_continuous_text_length) > 0) then ( number_of_substrings++; ); int length_of_last_substring = string_length - (max_continuous_text_length * (number_of_substrings - 1)); # if length of last substring is equal or smaller max_continuous_text_length_offset then don't break the last substring! bool break_last_substring = true; if (length_of_last_substring <= max_continuous_text_length_offset) then ( break_last_substring = false; ); # debug_message("#### Number of substrings modulo: " . number_of_substrings . "\n"); string new_string = ""; int substring_index = 0; for (int i = 1; i <= number_of_substrings; i++) ( if (i < (number_of_substrings - 1)) then ( new_string .= substr(ori_string, substring_index, max_continuous_text_length) . "__html__break__escape__variable__"; ) else if (i == (number_of_substrings - 1)) then ( if (break_last_substring) then ( new_string .= substr(ori_string, substring_index, max_continuous_text_length) . "__html__break__escape__variable__"; ) else ( new_string .= substr(ori_string, substring_index, max_continuous_text_length); ); ) else ( new_string .= substr(ori_string, substring_index, max_continuous_text_length); ); substring_index += max_continuous_text_length; ); new_string; )); subroutine(split_special( string ori_string, string main_divider, string destination_node, bool dash_breaks), ( string sub_divider; if (main_divider eq " ") then ( sub_divider = "-"; ) else ( sub_divider = " "; ); if (node_exists("volatile.temp.split_result")) then ( delete_node("volatile.temp.split_result"); ); split(ori_string, main_divider, "volatile.temp.split_result"); node item; string substring; int number_of_substrings = num_subnodes("volatile.temp.split_result"); int count = 0; # populate destination node by inserting a divider string node into the original split foreach item "volatile.temp.split_result" ( destination_node . "." . count = node_value(item); if ((count + 1) < number_of_substrings) then ( destination_node . "." . count . "_divider" = main_divider; ); count++; ); if (dash_breaks) then ( foreach item destination_node ( substring = node_value(item); if (contains(substring, sub_divider)) then ( # split the substring into substrings split_special(substring, sub_divider, item . ".subsubstrings", false); ); ); ); # if dash_breaks )); subroutine(combine_special( int max_continuous_text_length, int max_continuous_text_length_offset, string substrings_node), ( string new_string; string substring; string next_character; int substring_length; node item; foreach item substrings_node ( if (!node_exists(item . ".subsubstrings")) then ( substring = node_value(item); substring_length = length(substring); # debug_message("#### substring_length: " . substring_length . "\n"); if (substring_length > max_continuous_text_length) then ( substring = break_string(substring, substring_length, max_continuous_text_length, max_continuous_text_length_offset); # debug_message("#### returned substring after break: " . substring . "\n"); ); new_string = node_value("volatile.temp.recombined_string"); new_string .= substring; volatile.temp.recombined_string = new_string; ) else ( combine_special(max_continuous_text_length, max_continuous_text_length_offset, item . ".subsubstrings"); ); ); )); if (max_continuous_text_length > 0) then ( # debug_message("#### Break string is active\n"); # debug_message("#### Intact string: " . column_value . "\n"); int string_length = length(column_value); if (string_length > max_continuous_text_length) then ( bool contains_spaces = contains(column_value, " "); bool contains_dashes = contains(column_value, "-"); if ((contains_spaces or contains_dashes) and dash_breaks) then ( # ---------------------------------------------------- # break substrings only, divide by space and/or dashes # ---------------------------------------------------- if (node_exists("volatile.temp.substrings")) then ( delete_node("volatile.temp.substrings"); ); if (contains_spaces) then ( # split by spaces first split_special(column_value, " ", "volatile.temp.substrings", true); ) else ( # split by dashes split_special(column_value, "-", "volatile.temp.substrings", false); ); # debug_message("\n\noriginal string: " . column_value . "\n"); # debug_message(node_as_string("volatile.temp.substrings") . "\n"); volatile.temp.recombined_string = ""; combine_special(max_continuous_text_length, max_continuous_text_length_offset, "volatile.temp.substrings"); column_value = volatile.temp.recombined_string; # debug_message("new string: " . column_value . "\n\n"); ) else if (contains_spaces) then ( # ------------------------------------------- # break substrings only, divide by space only # ------------------------------------------- if (node_exists("volatile.temp.substrings")) then ( delete_node("volatile.temp.substrings"); ); split_special(column_value, " ", "volatile.temp.substrings", false); volatile.temp.recombined_string = ""; combine_special(max_continuous_text_length, max_continuous_text_length_offset, "volatile.temp.substrings"); column_value = volatile.temp.recombined_string; ) else ( # ----------------------- # break the single string # ----------------------- column_value = break_string(column_value, string_length, max_continuous_text_length, max_continuous_text_length_offset); ); ); ); # # # Escape string for html presentation # # # debug_message("\n#### column_value before string_to_html:" . column_value . "\n"); column_value = string_to_html(column_value); # debug_message("#### column_value after string_to_html:" . column_value . "\n\n"); #* if (contains(column_value, "&")) then ( column_value = replace_all(column_value, "&", "&"); ); if (contains(column_value, "<")) then ( column_value = replace_all(column_value, "<", "<"); ); if (contains(column_value, ">")) then ( column_value = replace_all(column_value, ">", ">"); ); if (contains(column_value, "$")) then ( column_value = replace_all(column_value, "$", "$"); ); if (contains(column_value, "%")) then ( column_value = replace_all(column_value, "%", "%"); ); *# # # # If string has been broken then replace __html__break__escape__variable__ with break_entity # # # break_entity depends on user agent and is defined in report_builder_standard # possible values are: , ​, or
if (contains(column_value, "__html__break__escape__variable__")) then ( column_value = replace_all(column_value, "__html__break__escape__variable__", break_entity); ); # debug_message("#### Column value final: " . column_value . "\n\n"); column_value; ));