View Issue Details
| ID | Project | Category | View Status | Date Submitted | Last Update |
|---|---|---|---|---|---|
| 20792 | Bug reports | Theme editor | public | 2026-10-22 16:16 | 2026-10-22 16:16 |
| Reporter | virgilev | Assigned To | |||
| Priority | none | Severity | minor | ||
| Status | new | Resolution | open | ||
| Product Version | 7.7.x | ||||
| Summary | 20792: New survey editor silently drops theme options not defined by fruity_twentythree | ||||
| Description | The new survey editor validates theme settings against a fixed schema that only lists the option names of fruity_twentythree (themeSettingUpdateJoi). A custom survey theme extending fruity_twentythree can declare extra options in its config.xml, including in optionsOrderReact. The editor shows these options but cannot save them: validation rejects the unknown keys before the request is sent. The server side already handles this correctly, since it only keeps the options declared in the theme manifest. The client-side whitelist is therefore not needed for safety. It only blocks custom themes. | ||||
| Steps To Reproduce | In Configuration > Themes, import custom_options_demo.zip. This is a minimal theme that extends fruity_twentythree and declares one extra option, headerBackgroundColor (colorpicker), listed in optionsOrderReact. Actual: The editor shows "Saved at …", but the value goes back to #ffffff after the reload. | ||||
| Tags | No tags attached. | ||||
| Attached Files | limesurvey_survey_custom_theme_options.lss (17,895 bytes)
<?xml version="1.0" encoding="UTF-8"?>
<document>
<LimeSurveyDocType>Survey</LimeSurveyDocType>
<DBVersion>648</DBVersion>
<languages>
<language>en</language>
</languages>
<groups>
<fields>
<fieldname>gid</fieldname>
<fieldname>sid</fieldname>
<fieldname>group_order</fieldname>
<fieldname>randomization_group</fieldname>
<fieldname>grelevance</fieldname>
</fields>
<rows>
<row>
<gid>35</gid>
<sid>426842</sid>
<group_order>1</group_order>
<randomization_group />
<grelevance>1</grelevance>
</row>
</rows>
</groups>
<group_l10ns>
<fields>
<fieldname>id</fieldname>
<fieldname>gid</fieldname>
<fieldname>group_name</fieldname>
<fieldname>description</fieldname>
<fieldname>language</fieldname>
<fieldname>sid</fieldname>
<fieldname>group_order</fieldname>
<fieldname>randomization_group</fieldname>
<fieldname>grelevance</fieldname>
</fields>
<rows>
<row>
<id>68</id>
<gid>35</gid>
<group_name>My first question group</group_name>
<description />
<language>en</language>
<sid>426842</sid>
<group_order>1</group_order>
<randomization_group />
<grelevance>1</grelevance>
</row>
</rows>
</group_l10ns>
<questions>
<fields>
<fieldname>qid</fieldname>
<fieldname>parent_qid</fieldname>
<fieldname>sid</fieldname>
<fieldname>gid</fieldname>
<fieldname>type</fieldname>
<fieldname>title</fieldname>
<fieldname>preg</fieldname>
<fieldname>other</fieldname>
<fieldname>mandatory</fieldname>
<fieldname>encrypted</fieldname>
<fieldname>question_order</fieldname>
<fieldname>scale_id</fieldname>
<fieldname>same_default</fieldname>
<fieldname>relevance</fieldname>
<fieldname>question_theme_name</fieldname>
<fieldname>modulename</fieldname>
<fieldname>same_script</fieldname>
</fields>
<rows>
<row>
<qid>469</qid>
<parent_qid>0</parent_qid>
<sid>426842</sid>
<gid>35</gid>
<type>T</type>
<title>G01Q05</title>
<preg />
<other>N</other>
<mandatory>N</mandatory>
<encrypted>N</encrypted>
<question_order>4</question_order>
<scale_id>0</scale_id>
<same_default>0</same_default>
<relevance>1</relevance>
<question_theme_name>longfreetext</question_theme_name>
<modulename />
<same_script>0</same_script>
</row>
</rows>
</questions>
<question_l10ns>
<fields>
<fieldname>id</fieldname>
<fieldname>qid</fieldname>
<fieldname>question</fieldname>
<fieldname>help</fieldname>
<fieldname>script</fieldname>
<fieldname>language</fieldname>
</fields>
<rows>
<row>
<id>931</id>
<qid>469</qid>
<question>Any comment?</question>
<help />
<script />
<language>en</language>
</row>
</rows>
</question_l10ns>
<question_attributes>
<fields>
<fieldname>qid</fieldname>
<fieldname>attribute</fieldname>
<fieldname>value</fieldname>
<fieldname>language</fieldname>
</fields>
<rows>
<row>
<qid>469</qid>
<attribute>cssclass</attribute>
<value />
<language />
</row>
<row>
<qid>469</qid>
<attribute>display_rows</attribute>
<value />
<language />
</row>
<row>
<qid>469</qid>
<attribute>em_validation_q</attribute>
<value />
<language />
</row>
<row>
<qid>469</qid>
<attribute>em_validation_q_tip</attribute>
<value />
<language>en</language>
</row>
<row>
<qid>469</qid>
<attribute>hidden</attribute>
<value>0</value>
<language />
</row>
<row>
<qid>469</qid>
<attribute>hide_tip</attribute>
<value>0</value>
<language />
</row>
<row>
<qid>469</qid>
<attribute>image</attribute>
<value />
<language />
</row>
<row>
<qid>469</qid>
<attribute>input_size</attribute>
<value />
<language />
</row>
<row>
<qid>469</qid>
<attribute>maximum_chars</attribute>
<value />
<language />
</row>
<row>
<qid>469</qid>
<attribute>page_break</attribute>
<value>0</value>
<language />
</row>
<row>
<qid>469</qid>
<attribute>random_group</attribute>
<value />
<language />
</row>
<row>
<qid>469</qid>
<attribute>save_as_default</attribute>
<value>N</value>
<language />
</row>
<row>
<qid>469</qid>
<attribute>statistics_graphtype</attribute>
<value>0</value>
<language />
</row>
<row>
<qid>469</qid>
<attribute>statistics_showgraph</attribute>
<value>1</value>
<language />
</row>
<row>
<qid>469</qid>
<attribute>text_input_width</attribute>
<value />
<language />
</row>
<row>
<qid>469</qid>
<attribute>time_limit</attribute>
<value />
<language />
</row>
<row>
<qid>469</qid>
<attribute>time_limit_action</attribute>
<value>1</value>
<language />
</row>
<row>
<qid>469</qid>
<attribute>time_limit_countdown_message</attribute>
<value />
<language>en</language>
</row>
<row>
<qid>469</qid>
<attribute>time_limit_disable_next</attribute>
<value>0</value>
<language />
</row>
<row>
<qid>469</qid>
<attribute>time_limit_disable_prev</attribute>
<value>0</value>
<language />
</row>
<row>
<qid>469</qid>
<attribute>time_limit_message</attribute>
<value />
<language>en</language>
</row>
<row>
<qid>469</qid>
<attribute>time_limit_message_delay</attribute>
<value />
<language />
</row>
<row>
<qid>469</qid>
<attribute>time_limit_message_style</attribute>
<value />
<language />
</row>
<row>
<qid>469</qid>
<attribute>time_limit_timer_style</attribute>
<value />
<language />
</row>
<row>
<qid>469</qid>
<attribute>time_limit_warning</attribute>
<value />
<language />
</row>
<row>
<qid>469</qid>
<attribute>time_limit_warning_2</attribute>
<value />
<language />
</row>
<row>
<qid>469</qid>
<attribute>time_limit_warning_2_display_time</attribute>
<value />
<language />
</row>
<row>
<qid>469</qid>
<attribute>time_limit_warning_2_message</attribute>
<value />
<language>en</language>
</row>
<row>
<qid>469</qid>
<attribute>time_limit_warning_2_style</attribute>
<value />
<language />
</row>
<row>
<qid>469</qid>
<attribute>time_limit_warning_display_time</attribute>
<value />
<language />
</row>
<row>
<qid>469</qid>
<attribute>time_limit_warning_message</attribute>
<value />
<language>en</language>
</row>
<row>
<qid>469</qid>
<attribute>time_limit_warning_style</attribute>
<value />
<language />
</row>
</rows>
</question_attributes>
<surveys>
<fields>
<fieldname>sid</fieldname>
<fieldname>gsid</fieldname>
<fieldname>admin</fieldname>
<fieldname>expires</fieldname>
<fieldname>startdate</fieldname>
<fieldname>adminemail</fieldname>
<fieldname>anonymized</fieldname>
<fieldname>format</fieldname>
<fieldname>savetimings</fieldname>
<fieldname>template</fieldname>
<fieldname>language</fieldname>
<fieldname>additional_languages</fieldname>
<fieldname>datestamp</fieldname>
<fieldname>usecookie</fieldname>
<fieldname>allowregister</fieldname>
<fieldname>allowsave</fieldname>
<fieldname>autonumber_start</fieldname>
<fieldname>autoredirect</fieldname>
<fieldname>allowprev</fieldname>
<fieldname>printanswers</fieldname>
<fieldname>ipaddr</fieldname>
<fieldname>ipanonymize</fieldname>
<fieldname>refurl</fieldname>
<fieldname>showsurveypolicynotice</fieldname>
<fieldname>publicstatistics</fieldname>
<fieldname>publicgraphs</fieldname>
<fieldname>listpublic</fieldname>
<fieldname>htmlemail</fieldname>
<fieldname>sendconfirmation</fieldname>
<fieldname>tokenanswerspersistence</fieldname>
<fieldname>assessments</fieldname>
<fieldname>usecaptcha</fieldname>
<fieldname>usetokens</fieldname>
<fieldname>bounce_email</fieldname>
<fieldname>attributedescriptions</fieldname>
<fieldname>emailresponseto</fieldname>
<fieldname>emailnotificationto</fieldname>
<fieldname>tokenlength</fieldname>
<fieldname>showxquestions</fieldname>
<fieldname>showgroupinfo</fieldname>
<fieldname>shownoanswer</fieldname>
<fieldname>showqnumcode</fieldname>
<fieldname>bouncetime</fieldname>
<fieldname>bounceprocessing</fieldname>
<fieldname>bounceaccounttype</fieldname>
<fieldname>bounceaccounthost</fieldname>
<fieldname>bounceaccountpass</fieldname>
<fieldname>bounceaccountencryption</fieldname>
<fieldname>bounceaccountuser</fieldname>
<fieldname>showwelcome</fieldname>
<fieldname>showprogress</fieldname>
<fieldname>questionindex</fieldname>
<fieldname>navigationdelay</fieldname>
<fieldname>alloweditaftercompletion</fieldname>
<fieldname>googleanalyticsstyle</fieldname>
<fieldname>googleanalyticsapikey</fieldname>
<fieldname>tokenencryptionoptions</fieldname>
<fieldname>access_mode</fieldname>
<fieldname>lastmodified</fieldname>
</fields>
<rows>
<row>
<sid>426842</sid>
<gsid>1</gsid>
<admin>inherit</admin>
<adminemail>inherit</adminemail>
<anonymized>I</anonymized>
<format>I</format>
<savetimings>I</savetimings>
<template>custom_options_demo</template>
<language>en</language>
<additional_languages />
<datestamp>I</datestamp>
<usecookie>I</usecookie>
<allowregister>I</allowregister>
<allowsave>I</allowsave>
<autonumber_start>0</autonumber_start>
<autoredirect>I</autoredirect>
<allowprev>I</allowprev>
<printanswers>I</printanswers>
<ipaddr>I</ipaddr>
<ipanonymize>I</ipanonymize>
<refurl>I</refurl>
<showsurveypolicynotice>0</showsurveypolicynotice>
<publicstatistics>I</publicstatistics>
<publicgraphs>I</publicgraphs>
<listpublic>I</listpublic>
<htmlemail>I</htmlemail>
<sendconfirmation>I</sendconfirmation>
<tokenanswerspersistence>I</tokenanswerspersistence>
<assessments>I</assessments>
<usecaptcha>E</usecaptcha>
<usetokens>N</usetokens>
<bounce_email>inherit</bounce_email>
<emailresponseto>inherit</emailresponseto>
<emailnotificationto>inherit</emailnotificationto>
<tokenlength>-1</tokenlength>
<showxquestions>N</showxquestions>
<showgroupinfo>I</showgroupinfo>
<shownoanswer>I</shownoanswer>
<showqnumcode>N</showqnumcode>
<bounceprocessing>N</bounceprocessing>
<showwelcome>I</showwelcome>
<showprogress>I</showprogress>
<questionindex>-1</questionindex>
<navigationdelay>-1</navigationdelay>
<alloweditaftercompletion>I</alloweditaftercompletion>
<tokenencryptionoptions />
<access_mode>O</access_mode>
<lastmodified>2026-10-22 00:00:00</lastmodified>
</row>
</rows>
</surveys>
<surveys_languagesettings>
<fields>
<fieldname>surveyls_survey_id</fieldname>
<fieldname>surveyls_policy_error</fieldname>
<fieldname>surveyls_email_invite_subj</fieldname>
<fieldname>surveyls_email_invite</fieldname>
<fieldname>surveyls_email_remind_subj</fieldname>
<fieldname>surveyls_email_remind</fieldname>
<fieldname>surveyls_email_register_subj</fieldname>
<fieldname>surveyls_email_register</fieldname>
<fieldname>surveyls_email_confirm_subj</fieldname>
<fieldname>surveyls_email_confirm</fieldname>
<fieldname>surveyls_dateformat</fieldname>
<fieldname>surveyls_attributecaptions</fieldname>
<fieldname>surveyls_alias</fieldname>
<fieldname>email_admin_notification_subj</fieldname>
<fieldname>email_admin_notification</fieldname>
<fieldname>email_admin_responses_subj</fieldname>
<fieldname>email_admin_responses</fieldname>
<fieldname>surveyls_numberformat</fieldname>
<fieldname>attachments</fieldname>
<fieldname>surveyls_language</fieldname>
<fieldname>surveyls_title</fieldname>
<fieldname>surveyls_description</fieldname>
<fieldname>surveyls_welcometext</fieldname>
<fieldname>surveyls_endtext</fieldname>
<fieldname>surveyls_policy_notice</fieldname>
<fieldname>surveyls_policy_notice_label</fieldname>
<fieldname>surveyls_url</fieldname>
<fieldname>surveyls_urldescription</fieldname>
</fields>
<rows>
<row>
<surveyls_survey_id>426842</surveyls_survey_id>
<surveyls_policy_error />
<surveyls_email_invite_subj>Invitation to participate in a survey</surveyls_email_invite_subj>
<surveyls_email_invite>Dear {FIRSTNAME},<br />
<br />
You have been invited to participate in a survey.<br />
<br />
The survey is titled:<br />
"{SURVEYNAME}"<br />
<br />
"{SURVEYDESCRIPTION}"<br />
<br />
To participate, please click on the link below.<br />
<br />
Sincerely,<br />
<br />
{ADMINNAME} ({ADMINEMAIL})<br />
<br />
----------------------------------------------<br />
Click here to do the survey:<br />
{SURVEYURL}<br />
<br />
If you do not want to participate in this survey and don't want to receive any more invitations please click the following link:<br />
{OPTOUTURL}<br />
<br />
If you are blocklisted but want to participate in this survey and want to receive invitations please click the following link:<br />
{OPTINURL}</surveyls_email_invite>
<surveyls_email_remind_subj>Reminder to participate in a survey</surveyls_email_remind_subj>
<surveyls_email_remind>Dear {FIRSTNAME},<br />
<br />
Recently we invited you to participate in a survey.<br />
<br />
We note that you have not yet completed the survey, and wish to remind you that the survey is still available should you wish to take part.<br />
<br />
The survey is titled:<br />
"{SURVEYNAME}"<br />
<br />
"{SURVEYDESCRIPTION}"<br />
<br />
To participate, please click on the link below.<br />
<br />
Sincerely,<br />
<br />
{ADMINNAME} ({ADMINEMAIL})<br />
<br />
----------------------------------------------<br />
Click here to do the survey:<br />
{SURVEYURL}<br />
<br />
If you do not want to participate in this survey and don't want to receive any more invitations please click the following link:<br />
{OPTOUTURL}</surveyls_email_remind>
<surveyls_email_register_subj>Survey registration confirmation</surveyls_email_register_subj>
<surveyls_email_register>Dear {FIRSTNAME},<br />
<br />
You, or someone using your email address, have registered to participate in an online survey titled {SURVEYNAME}.<br />
<br />
To complete this survey, click on the following URL:<br />
<br />
{SURVEYURL}<br />
<br />
If you have any questions about this survey, or if you did not register to participate and believe this email is in error, please contact {ADMINNAME} at {ADMINEMAIL}.</surveyls_email_register>
<surveyls_email_confirm_subj>Confirmation of your participation in our survey</surveyls_email_confirm_subj>
<surveyls_email_confirm>Dear {FIRSTNAME},<br />
<br />
This email is to confirm that you have completed the survey titled {SURVEYNAME} and your response has been saved. Thank you for participating.<br />
<br />
If you have any further questions about this email, please contact {ADMINNAME} on {ADMINEMAIL}.<br />
<br />
Sincerely,<br />
<br />
{ADMINNAME}</surveyls_email_confirm>
<surveyls_dateformat>9</surveyls_dateformat>
<surveyls_alias />
<email_admin_notification_subj>Response submission for survey {SURVEYNAME}</email_admin_notification_subj>
<email_admin_notification>Hello,<br />
<br />
A new response was submitted for your survey '{SURVEYNAME}'.<br />
<br />
Click the following link to see the individual response:<br />
{VIEWRESPONSEURL}<br />
<br />
Click the following link to edit the individual response:<br />
{EDITRESPONSEURL}<br />
<br />
View statistics by clicking here:<br />
{STATISTICSURL}</email_admin_notification>
<email_admin_responses_subj>Response submission for survey {SURVEYNAME} with results</email_admin_responses_subj>
<email_admin_responses>Hello,<br />
<br />
A new response was submitted for your survey '{SURVEYNAME}'.<br />
<br />
Click the following link to see the individual response:<br />
{VIEWRESPONSEURL}<br />
<br />
Click the following link to edit the individual response:<br />
{EDITRESPONSEURL}<br />
<br />
View statistics by clicking here:<br />
{STATISTICSURL}<br />
<br />
<br />
The following answers were given by the participant:<br />
{ANSWERTABLE}</email_admin_responses>
<surveyls_numberformat>0</surveyls_numberformat>
<surveyls_language>en</surveyls_language>
<surveyls_title>Custom theme options</surveyls_title>
<surveyls_description />
<surveyls_welcometext />
<surveyls_endtext />
<surveyls_policy_notice />
<surveyls_policy_notice_label />
<surveyls_url />
<surveyls_urldescription />
</row>
</rows>
</surveys_languagesettings>
<surveys_groups>
<fields>
<fieldname>gsid</fieldname>
<fieldname>name</fieldname>
<fieldname>title</fieldname>
<fieldname>template</fieldname>
<fieldname>description</fieldname>
<fieldname>parent_id</fieldname>
<fieldname>alwaysavailable</fieldname>
</fields>
<rows>
<row>
<gsid>1</gsid>
<name>default</name>
<title>Default</title>
<description>Default survey group</description>
</row>
</rows>
</surveys_groups>
</document> | ||||
| Bug heat | 0 | ||||
| Complete LimeSurvey version number (& build) | 7.5.1+261007 (also present in 7.7.0 and the current development branch) | ||||
| I will donate to the project if issue is resolved | No | ||||
| Browser | |||||
| Database type & version | PostgreSQL 18.6 | ||||
| Server OS (if known) | |||||
| Webserver software & version (if known) | |||||
| PHP Version | 8.4.27 | ||||
| Git branch / Pull Request URL | |||||