From b773d734decae383bf76da43b9144384fffad9af Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 21 Nov 2025 15:38:35 +0000 Subject: [PATCH 1/5] Initial plan From 4028d4bcd6ad9e1eed4c5707614352034d16bcc0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 21 Nov 2025 15:44:01 +0000 Subject: [PATCH 2/5] Add XML character escaping for enum values in XSLT transformation generator Co-authored-by: Markus1812 <7271378+Markus1812@users.noreply.github.com> --- src/zcl_aff_test_types.clas.abap | 23 ++++++++++++ src/zcl_aff_writer_xslt.clas.abap | 23 ++++++++++-- src/zcl_aff_writer_xslt.clas.testclasses.abap | 36 ++++++++++++++++++- 3 files changed, 78 insertions(+), 4 deletions(-) diff --git a/src/zcl_aff_test_types.clas.abap b/src/zcl_aff_test_types.clas.abap index 1a58bd01..d0597e4d 100644 --- a/src/zcl_aff_test_types.clas.abap +++ b/src/zcl_aff_test_types.clas.abap @@ -971,6 +971,29 @@ CLASS zcl_aff_test_types DEFINITION enum_component TYPE c LENGTH 2, END OF struc_with_own_enum_values. + CONSTANTS: + BEGIN OF co_enum_special_chars, + "!

Less Than

+ "! Less than + less_than TYPE c LENGTH 1 VALUE '<', + "!

Greater Than

+ "! Greater than + greater_than TYPE c LENGTH 1 VALUE '>', + "!

Ampersand

+ "! Ampersand + ampersand TYPE c LENGTH 1 VALUE '&', + END OF co_enum_special_chars. + + TYPES: + "!

Structure With Special Character Enum Values

+ "! Structure with special character enum values + BEGIN OF struc_with_special_char_enums, + "!

Enum With Special Characters

+ "! Enum with special characters + "! $values {@link zcl_aff_test_types.data:co_enum_special_chars } + special_char_enum TYPE c LENGTH 1, + END OF struc_with_special_char_enums. + CLASS-DATA subschema TYPE string_table. CLASS-DATA expected_var TYPE REF TO data. diff --git a/src/zcl_aff_writer_xslt.clas.abap b/src/zcl_aff_writer_xslt.clas.abap index 6729b3b3..5937fc47 100644 --- a/src/zcl_aff_writer_xslt.clas.abap +++ b/src/zcl_aff_writer_xslt.clas.abap @@ -206,7 +206,12 @@ CLASS zcl_aff_writer_xslt DEFINITION get_to_ref IMPORTING name TYPE string - RETURNING VALUE(result) TYPE string. + RETURNING VALUE(result) TYPE string, + escape_xml_chars + IMPORTING + value TYPE string + RETURNING + VALUE(result) TYPE string. ENDCLASS. @@ -459,6 +464,7 @@ CLASS zcl_aff_writer_xslt IMPLEMENTATION. METHOD get_abap_value. DATA abap_value_copy TYPE string. + DATA escaped_value TYPE string. CASE element_description->type_kind. WHEN cl_abap_typedescr=>typekind_int OR cl_abap_typedescr=>typekind_int1 OR cl_abap_typedescr=>typekind_int2 OR cl_abap_typedescr=>typekind_int8. @@ -466,9 +472,11 @@ CLASS zcl_aff_writer_xslt IMPLEMENTATION. CONDENSE abap_value_copy. result = |I({ abap_value_copy })|. WHEN cl_abap_typedescr=>typekind_num. - result = |N('{ abap_value }')|. + escaped_value = escape_xml_chars( abap_value ). + result = |N('{ escaped_value }')|. WHEN OTHERS. - result = |'{ abap_value }'|. + escaped_value = escape_xml_chars( abap_value ). + result = |'{ escaped_value }'|. ENDCASE. ENDMETHOD. @@ -806,4 +814,13 @@ CLASS zcl_aff_writer_xslt IMPLEMENTATION. ENDLOOP. ENDMETHOD. + METHOD escape_xml_chars. + result = value. + REPLACE ALL OCCURRENCES OF '<' IN result WITH '<'. + REPLACE ALL OCCURRENCES OF '>' IN result WITH '>'. + REPLACE ALL OCCURRENCES OF '&' IN result WITH '&'. + REPLACE ALL OCCURRENCES OF '"' IN result WITH '"'. + REPLACE ALL OCCURRENCES OF '''' IN result WITH '''. + ENDMETHOD. + ENDCLASS. diff --git a/src/zcl_aff_writer_xslt.clas.testclasses.abap b/src/zcl_aff_writer_xslt.clas.testclasses.abap index 053ae6ff..a04dab98 100644 --- a/src/zcl_aff_writer_xslt.clas.testclasses.abap +++ b/src/zcl_aff_writer_xslt.clas.testclasses.abap @@ -1172,7 +1172,8 @@ CLASS ltcl_type_writer_xslt_ad DEFINITION FINAL FOR TESTING wrong_default_type_link FOR TESTING RAISING cx_static_check, structure_with_enums FOR TESTING RAISING cx_static_check, structure_with_default_problem FOR TESTING RAISING cx_static_check, - struc_with_own_enum_values FOR TESTING RAISING cx_static_check. + struc_with_own_enum_values FOR TESTING RAISING cx_static_check, + struc_with_special_char_enums FOR TESTING RAISING cx_static_check. ENDCLASS. CLASS ltcl_type_writer_xslt_ad IMPLEMENTATION. @@ -2412,6 +2413,39 @@ CLASS ltcl_type_writer_xslt_ad IMPLEMENTATION. validate_output( act_output ). ENDMETHOD. + METHOD struc_with_special_char_enums. + DATA test_type TYPE zcl_aff_test_types=>struc_with_special_char_enums. + DATA(act_output) = test_generator->generate_type( test_type ). + me->exp_transformation = VALUE #( + ( `` ) + ( ` ` ) + ( ` ` ) + ( ` ` ) + ( ` ` ) + ( ` ` ) + ( ` ` ) + ( ` ` ) + ( ` ` ) + ( ` <_ tt:lax="on">` ) + ( ` ` ) + ( ` ` ) + ( ` ` ) + ( ` ` ) + ( ` ` ) + ( ` ` ) + ( ` ` ) + ( ` <__/>` ) + ( ` ` ) + ( ` ` ) + ( ` ` ) + ( `` ) ). + validate_output( act_output ). + ENDMETHOD. + METHOD validate_output. DATA exp TYPE string_table. From 0bf3564aa773f60cabad5a4170212f0782c85023 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 21 Nov 2025 15:45:08 +0000 Subject: [PATCH 3/5] Fix escape order to prevent double-escaping Co-authored-by: Markus1812 <7271378+Markus1812@users.noreply.github.com> --- src/zcl_aff_writer_xslt.clas.abap | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/zcl_aff_writer_xslt.clas.abap b/src/zcl_aff_writer_xslt.clas.abap index 5937fc47..33dde081 100644 --- a/src/zcl_aff_writer_xslt.clas.abap +++ b/src/zcl_aff_writer_xslt.clas.abap @@ -816,9 +816,10 @@ CLASS zcl_aff_writer_xslt IMPLEMENTATION. METHOD escape_xml_chars. result = value. + " Ampersand must be replaced first to avoid double-escaping + REPLACE ALL OCCURRENCES OF '&' IN result WITH '&'. REPLACE ALL OCCURRENCES OF '<' IN result WITH '<'. REPLACE ALL OCCURRENCES OF '>' IN result WITH '>'. - REPLACE ALL OCCURRENCES OF '&' IN result WITH '&'. REPLACE ALL OCCURRENCES OF '"' IN result WITH '"'. REPLACE ALL OCCURRENCES OF '''' IN result WITH '''. ENDMETHOD. From c6576d2eec28c62273534bd5d181ef61134bfb34 Mon Sep 17 00:00:00 2001 From: Markus Date: Mon, 1 Dec 2025 09:16:29 +0100 Subject: [PATCH 4/5] Update src/zcl_aff_writer_xslt.clas.testclasses.abap --- src/zcl_aff_writer_xslt.clas.testclasses.abap | 1 - 1 file changed, 1 deletion(-) diff --git a/src/zcl_aff_writer_xslt.clas.testclasses.abap b/src/zcl_aff_writer_xslt.clas.testclasses.abap index a74d87de..17b382ef 100644 --- a/src/zcl_aff_writer_xslt.clas.testclasses.abap +++ b/src/zcl_aff_writer_xslt.clas.testclasses.abap @@ -1298,7 +1298,6 @@ CLASS ltcl_type_writer_xslt_ad DEFINITION FINAL FOR TESTING structure_with_default_problem FOR TESTING RAISING cx_static_check, struc_with_own_enum_values FOR TESTING RAISING cx_static_check, struc_with_special_char_enums FOR TESTING RAISING cx_static_check, - struc_with_own_enum_values FOR TESTING RAISING cx_static_check, enable_extension FOR TESTING RAISING cx_static_check. ENDCLASS. From 5fb3ed043e4be66d2fa9d990e6514bf813c7e55e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 2 Dec 2025 07:57:05 +0000 Subject: [PATCH 5/5] Add integration test for struc_with_special_char_enums Co-authored-by: Markus1812 <7271378+Markus1812@users.noreply.github.com> --- src/zcl_aff_writer_xslt.clas.testclasses.abap | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/zcl_aff_writer_xslt.clas.testclasses.abap b/src/zcl_aff_writer_xslt.clas.testclasses.abap index 17b382ef..c6aa4770 100644 --- a/src/zcl_aff_writer_xslt.clas.testclasses.abap +++ b/src/zcl_aff_writer_xslt.clas.testclasses.abap @@ -2687,6 +2687,8 @@ RISK LEVEL DANGEROUS. struc_with_own_enum_values FOR TESTING RAISING cx_static_check, + struc_with_special_char_enums FOR TESTING RAISING cx_static_check, + from_abap_to_json IMPORTING test_type TYPE data @@ -3258,6 +3260,40 @@ CLASS ltcl_integration_test_ad IMPLEMENTATION. act_data = test_type ). ENDMETHOD. + METHOD struc_with_special_char_enums. + DATA test_type TYPE zcl_aff_test_types=>struc_with_special_char_enums. + test_type = VALUE #( special_char_enum = '<' ). + exp_json = VALUE #( + ( `{` ) + ( ` "specialCharEnum": "lessThan"` ) + ( `}` ) ). + do_integration_test( + EXPORTING + test_type = test_type + CHANGING + act_data = test_type ). + test_type = VALUE #( special_char_enum = '>' ). + exp_json = VALUE #( + ( `{` ) + ( ` "specialCharEnum": "greaterThan"` ) + ( `}` ) ). + do_integration_test( + EXPORTING + test_type = test_type + CHANGING + act_data = test_type ). + test_type = VALUE #( special_char_enum = '&' ). + exp_json = VALUE #( + ( `{` ) + ( ` "specialCharEnum": "ampersand"` ) + ( `}` ) ). + do_integration_test( + EXPORTING + test_type = test_type + CHANGING + act_data = test_type ). + ENDMETHOD. + METHOD do_integration_test. from_abap_to_json( EXPORTING