Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/assets/javascripts/static_site_editor/components/edit_area.vue4
-rw-r--r--app/assets/javascripts/static_site_editor/graphql/index.js4
-rw-r--r--app/assets/javascripts/static_site_editor/graphql/queries/app_data.query.graphql4
-rw-r--r--app/assets/javascripts/static_site_editor/graphql/typedefs.graphql6
-rw-r--r--app/assets/javascripts/static_site_editor/index.js4
-rw-r--r--app/assets/javascripts/static_site_editor/pages/home.vue1
-rw-r--r--changelogs/unreleased/257822-null-byes-in-url.yml5
-rw-r--r--config/application.rb4
-rw-r--r--doc/administration/raketasks/check.md6
-rw-r--r--doc/administration/timezone.md6
-rw-r--r--doc/administration/uploads.md6
-rw-r--r--doc/administration/user_settings.md6
-rw-r--r--doc/api/admin_sidekiq_queues.md6
-rw-r--r--doc/api/api_resources.md6
-rw-r--r--doc/api/appearance.md6
-rw-r--r--doc/api/applications.md6
-rw-r--r--doc/api/audit_events.md6
-rw-r--r--doc/api/avatar.md6
-rw-r--r--doc/api/broadcast_messages.md6
-rw-r--r--doc/api/custom_attributes.md6
-rw-r--r--doc/api/dependencies.md6
-rw-r--r--doc/api/dependency_proxy.md6
-rw-r--r--doc/api/epic_links.md6
-rw-r--r--doc/api/events.md6
-rw-r--r--doc/api/geo_nodes.md6
-rw-r--r--doc/api/graphql/audit_report.md6
-rw-r--r--doc/api/graphql/getting_started.md6
-rw-r--r--doc/api/graphql/index.md6
-rw-r--r--doc/api/graphql/sample_issue_boards.md6
-rw-r--r--doc/api/group_activity_analytics.md6
-rw-r--r--doc/api/group_badges.md6
-rw-r--r--doc/api/group_import_export.md6
-rw-r--r--doc/user/group/epics/manage_epics.md48
-rw-r--r--lib/api/api.rb3
-rw-r--r--lib/gitlab/ci/templates/Security/SAST.gitlab-ci.yml2
-rw-r--r--lib/gitlab/etag_caching/middleware.rb8
-rw-r--r--lib/gitlab/etag_caching/router.rb44
-rw-r--r--lib/gitlab/grape_logging/loggers/content_logger.rb16
-rw-r--r--lib/gitlab/middleware/handle_malformed_strings.rb (renamed from lib/gitlab/middleware/handle_null_bytes.rb)19
-rw-r--r--spec/features/merge_request/user_suggests_changes_on_diff_spec.rb2
-rw-r--r--spec/frontend/static_site_editor/components/edit_area_spec.js2
-rw-r--r--spec/frontend/static_site_editor/mock_data.js7
-rw-r--r--spec/frontend/static_site_editor/pages/home_spec.js3
-rw-r--r--spec/lib/gitlab/etag_caching/middleware_spec.rb15
-rw-r--r--spec/lib/gitlab/etag_caching/router_spec.rb8
-rw-r--r--spec/lib/gitlab/middleware/handle_malformed_strings_spec.rb109
-rw-r--r--spec/lib/gitlab/middleware/handle_null_bytes_spec.rb88
-rw-r--r--spec/requests/user_sends_malformed_strings_spec.rb20
-rw-r--r--spec/requests/user_sends_null_bytes_spec.rb14
49 files changed, 425 insertions, 159 deletions
diff --git a/app/assets/javascripts/static_site_editor/components/edit_area.vue b/app/assets/javascripts/static_site_editor/components/edit_area.vue
index e602f26acdf..56f1a26f005 100644
--- a/app/assets/javascripts/static_site_editor/components/edit_area.vue
+++ b/app/assets/javascripts/static_site_editor/components/edit_area.vue
@@ -37,6 +37,10 @@ export default {
required: false,
default: '',
},
+ mounts: {
+ type: Array,
+ required: true,
+ },
imageRoot: {
type: String,
required: false,
diff --git a/app/assets/javascripts/static_site_editor/graphql/index.js b/app/assets/javascripts/static_site_editor/graphql/index.js
index cc68bc57bb0..a13f7d3ad53 100644
--- a/app/assets/javascripts/static_site_editor/graphql/index.js
+++ b/app/assets/javascripts/static_site_editor/graphql/index.js
@@ -25,11 +25,15 @@ const createApolloProvider = appData => {
},
);
+ // eslint-disable-next-line @gitlab/require-i18n-strings
+ const mounts = appData.mounts.map(mount => ({ __typename: 'Mount', ...mount }));
+
defaultClient.cache.writeData({
data: {
appData: {
__typename: 'AppData',
...appData,
+ mounts,
},
},
});
diff --git a/app/assets/javascripts/static_site_editor/graphql/queries/app_data.query.graphql b/app/assets/javascripts/static_site_editor/graphql/queries/app_data.query.graphql
index 9f4b0afe55f..3b377b9288a 100644
--- a/app/assets/javascripts/static_site_editor/graphql/queries/app_data.query.graphql
+++ b/app/assets/javascripts/static_site_editor/graphql/queries/app_data.query.graphql
@@ -6,5 +6,9 @@ query appData {
sourcePath
username
returnUrl
+ mounts {
+ source
+ target
+ }
}
}
diff --git a/app/assets/javascripts/static_site_editor/graphql/typedefs.graphql b/app/assets/javascripts/static_site_editor/graphql/typedefs.graphql
index 0ded1722d26..b8808f4e425 100644
--- a/app/assets/javascripts/static_site_editor/graphql/typedefs.graphql
+++ b/app/assets/javascripts/static_site_editor/graphql/typedefs.graphql
@@ -14,6 +14,11 @@ type SavedContentMeta {
branch: SavedContentField!
}
+type Mount {
+ source: String!
+ target: String
+}
+
type AppData {
isSupportedContent: Boolean!
hasSubmittedChanges: Boolean!
@@ -21,6 +26,7 @@ type AppData {
returnUrl: String
sourcePath: String!
username: String!
+ mounts: [Mount]!
}
input HasSubmittedChangesInput {
diff --git a/app/assets/javascripts/static_site_editor/index.js b/app/assets/javascripts/static_site_editor/index.js
index fceef8f9084..ceb1d820c83 100644
--- a/app/assets/javascripts/static_site_editor/index.js
+++ b/app/assets/javascripts/static_site_editor/index.js
@@ -20,9 +20,6 @@ const initStaticSiteEditor = el => {
imageUploadPath,
mounts,
} = el.dataset;
- // NOTE that the object in 'mounts' is a JSON string from the data attribute, so it must be parsed into an object.
- // eslint-disable-next-line no-unused-vars
- const mountsObject = JSON.parse(mounts);
const { current_username: username } = window.gon;
const returnUrl = el.dataset.returnUrl || null;
const router = createRouter(baseUrl);
@@ -30,6 +27,7 @@ const initStaticSiteEditor = el => {
isSupportedContent: parseBoolean(isSupportedContent),
hasSubmittedChanges: false,
project: `${namespace}/${project}`,
+ mounts: JSON.parse(mounts), // NOTE that the object in 'mounts' is a JSON string from the data attribute, so it must be parsed into an object.
returnUrl,
sourcePath,
username,
diff --git a/app/assets/javascripts/static_site_editor/pages/home.vue b/app/assets/javascripts/static_site_editor/pages/home.vue
index 27bd1c99ae2..d7e52ef9c45 100644
--- a/app/assets/javascripts/static_site_editor/pages/home.vue
+++ b/app/assets/javascripts/static_site_editor/pages/home.vue
@@ -138,6 +138,7 @@ export default {
:content="sourceContent.content"
:saving-changes="isSavingChanges"
:return-url="appData.returnUrl"
+ :mounts="appData.mounts"
@submit="onPrepareSubmit"
/>
<edit-meta-modal
diff --git a/changelogs/unreleased/257822-null-byes-in-url.yml b/changelogs/unreleased/257822-null-byes-in-url.yml
new file mode 100644
index 00000000000..6d9ef42929a
--- /dev/null
+++ b/changelogs/unreleased/257822-null-byes-in-url.yml
@@ -0,0 +1,5 @@
+---
+title: Handle malformed strings in URL
+merge_request: 45701
+author:
+type: fixed
diff --git a/config/application.rb b/config/application.rb
index 6f479468d6f..ab0bf061e47 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -28,7 +28,7 @@ module Gitlab
require_dependency Rails.root.join('lib/gitlab/middleware/basic_health_check')
require_dependency Rails.root.join('lib/gitlab/middleware/same_site_cookies')
require_dependency Rails.root.join('lib/gitlab/middleware/handle_ip_spoof_attack_error')
- require_dependency Rails.root.join('lib/gitlab/middleware/handle_null_bytes')
+ require_dependency Rails.root.join('lib/gitlab/middleware/handle_malformed_strings')
require_dependency Rails.root.join('lib/gitlab/runtime')
# Settings in config/environments/* take precedence over those specified here.
@@ -257,7 +257,7 @@ module Gitlab
config.middleware.insert_before ActionDispatch::RemoteIp, ::Gitlab::Middleware::HandleIpSpoofAttackError
- config.middleware.use ::Gitlab::Middleware::HandleNullBytes
+ config.middleware.insert_after ActionDispatch::ActionableExceptions, ::Gitlab::Middleware::HandleMalformedStrings
# Allow access to GitLab API from other domains
config.middleware.insert_before Warden::Manager, Rack::Cors do
diff --git a/doc/administration/raketasks/check.md b/doc/administration/raketasks/check.md
index bdccd6d5fe9..f61a3107b3d 100644
--- a/doc/administration/raketasks/check.md
+++ b/doc/administration/raketasks/check.md
@@ -1,3 +1,9 @@
+---
+stage: none
+group: unassigned
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
+---
+
# Integrity check Rake task **(CORE ONLY)**
GitLab provides Rake tasks to check the integrity of various components.
diff --git a/doc/administration/timezone.md b/doc/administration/timezone.md
index 3cfee8630b7..4bedd219203 100644
--- a/doc/administration/timezone.md
+++ b/doc/administration/timezone.md
@@ -1,3 +1,9 @@
+---
+stage: none
+group: unassigned
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
+---
+
# Changing your time zone
The global time zone configuration parameter can be changed in `config/gitlab.yml`:
diff --git a/doc/administration/uploads.md b/doc/administration/uploads.md
index 91de089c45e..f0e126176b6 100644
--- a/doc/administration/uploads.md
+++ b/doc/administration/uploads.md
@@ -1,3 +1,9 @@
+---
+stage: none
+group: unassigned
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
+---
+
# Uploads administration **(CORE ONLY)**
Uploads represent all user data that may be sent to GitLab as a single file. As an example, avatars and notes' attachments are uploads. Uploads are integral to GitLab functionality, and therefore cannot be disabled.
diff --git a/doc/administration/user_settings.md b/doc/administration/user_settings.md
index 7a3e1d86712..94ce1debfea 100644
--- a/doc/administration/user_settings.md
+++ b/doc/administration/user_settings.md
@@ -1,3 +1,9 @@
+---
+stage: none
+group: unassigned
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
+---
+
# Modifying global user settings
GitLab administrators can modify user settings for the entire GitLab instance.
diff --git a/doc/api/admin_sidekiq_queues.md b/doc/api/admin_sidekiq_queues.md
index 22488d053b4..8e1f7260208 100644
--- a/doc/api/admin_sidekiq_queues.md
+++ b/doc/api/admin_sidekiq_queues.md
@@ -1,3 +1,9 @@
+---
+stage: none
+group: unassigned
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
+---
+
# Sidekiq queues administration API **(CORE ONLY)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/25998) in GitLab 12.9
diff --git a/doc/api/api_resources.md b/doc/api/api_resources.md
index 199b244b2c3..436a0eb93f1 100644
--- a/doc/api/api_resources.md
+++ b/doc/api/api_resources.md
@@ -1,3 +1,9 @@
+---
+stage: none
+group: unassigned
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
+---
+
# API resources
Available resources for the [GitLab API](README.md) can be grouped in the following contexts:
diff --git a/doc/api/appearance.md b/doc/api/appearance.md
index 47a9d48a4ae..ad44c93ce32 100644
--- a/doc/api/appearance.md
+++ b/doc/api/appearance.md
@@ -1,3 +1,9 @@
+---
+stage: none
+group: unassigned
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
+---
+
# Appearance API **(CORE ONLY)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/16647) in GitLab 12.7.
diff --git a/doc/api/applications.md b/doc/api/applications.md
index 379f346c019..a3216bdddde 100644
--- a/doc/api/applications.md
+++ b/doc/api/applications.md
@@ -1,3 +1,9 @@
+---
+stage: none
+group: unassigned
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
+---
+
# Applications API
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/8160) in GitLab 10.5.
diff --git a/doc/api/audit_events.md b/doc/api/audit_events.md
index 5f31919c52b..5fdf0c20f1a 100644
--- a/doc/api/audit_events.md
+++ b/doc/api/audit_events.md
@@ -1,3 +1,9 @@
+---
+stage: none
+group: unassigned
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
+---
+
# Audit Events API
## Instance Audit Events **(PREMIUM ONLY)**
diff --git a/doc/api/avatar.md b/doc/api/avatar.md
index 223704d3e6c..aec1ba67d45 100644
--- a/doc/api/avatar.md
+++ b/doc/api/avatar.md
@@ -1,3 +1,9 @@
+---
+stage: none
+group: unassigned
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
+---
+
# Avatar API
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/19121) in GitLab 11.0.
diff --git a/doc/api/broadcast_messages.md b/doc/api/broadcast_messages.md
index 37156186d03..3d243b2a03f 100644
--- a/doc/api/broadcast_messages.md
+++ b/doc/api/broadcast_messages.md
@@ -1,3 +1,9 @@
+---
+stage: none
+group: unassigned
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
+---
+
# Broadcast Messages API
> Introduced in GitLab 8.12.
diff --git a/doc/api/custom_attributes.md b/doc/api/custom_attributes.md
index 07ece99f9b1..76c8474ee95 100644
--- a/doc/api/custom_attributes.md
+++ b/doc/api/custom_attributes.md
@@ -1,3 +1,9 @@
+---
+stage: none
+group: unassigned
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
+---
+
# Custom Attributes API
Every API call to custom attributes must be authenticated as administrator.
diff --git a/doc/api/dependencies.md b/doc/api/dependencies.md
index 56d33bf151a..2f65ff7b8d9 100644
--- a/doc/api/dependencies.md
+++ b/doc/api/dependencies.md
@@ -1,3 +1,9 @@
+---
+stage: none
+group: unassigned
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
+---
+
# Dependencies API **(ULTIMATE)**
CAUTION: **Caution:**
diff --git a/doc/api/dependency_proxy.md b/doc/api/dependency_proxy.md
index a379f1481c1..fb100cc90d8 100644
--- a/doc/api/dependency_proxy.md
+++ b/doc/api/dependency_proxy.md
@@ -1,3 +1,9 @@
+---
+stage: none
+group: unassigned
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
+---
+
# Dependency Proxy API **(PREMIUM)**
## Purge the dependency proxy for a group
diff --git a/doc/api/epic_links.md b/doc/api/epic_links.md
index 19c8dc78aed..c4afb1e7299 100644
--- a/doc/api/epic_links.md
+++ b/doc/api/epic_links.md
@@ -1,3 +1,9 @@
+---
+stage: none
+group: unassigned
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
+---
+
# Epic Links API **(ULTIMATE)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/9188) in GitLab 11.8.
diff --git a/doc/api/events.md b/doc/api/events.md
index 3f4f11b9786..4da4bfe8bd4 100644
--- a/doc/api/events.md
+++ b/doc/api/events.md
@@ -1,3 +1,9 @@
+---
+stage: none
+group: unassigned
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
+---
+
# Events
## Filter parameters
diff --git a/doc/api/geo_nodes.md b/doc/api/geo_nodes.md
index 064bd26ee72..f198b4f4aa2 100644
--- a/doc/api/geo_nodes.md
+++ b/doc/api/geo_nodes.md
@@ -1,3 +1,9 @@
+---
+stage: none
+group: unassigned
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
+---
+
# Geo Nodes API **(PREMIUM ONLY)**
To interact with Geo node endpoints, you need to authenticate yourself as an
diff --git a/doc/api/graphql/audit_report.md b/doc/api/graphql/audit_report.md
index 36c3f44ff89..12663654026 100644
--- a/doc/api/graphql/audit_report.md
+++ b/doc/api/graphql/audit_report.md
@@ -1,3 +1,9 @@
+---
+stage: none
+group: unassigned
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
+---
+
# Set up an Audit Report with GraphQL
This page describes how you can use the GraphiQL explorer to set up an audit report
diff --git a/doc/api/graphql/getting_started.md b/doc/api/graphql/getting_started.md
index c2220403461..8501e76b5aa 100644
--- a/doc/api/graphql/getting_started.md
+++ b/doc/api/graphql/getting_started.md
@@ -1,3 +1,9 @@
+---
+stage: none
+group: unassigned
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
+---
+
# Getting started with GitLab GraphQL API
This guide demonstrates basic usage of GitLab's GraphQL API.
diff --git a/doc/api/graphql/index.md b/doc/api/graphql/index.md
index bda24a7e90a..e0557db6567 100644
--- a/doc/api/graphql/index.md
+++ b/doc/api/graphql/index.md
@@ -1,3 +1,9 @@
+---
+stage: none
+group: unassigned
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
+---
+
# GraphQL API
> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/19008) in GitLab 11.0 (enabled by feature flag `graphql`).
diff --git a/doc/api/graphql/sample_issue_boards.md b/doc/api/graphql/sample_issue_boards.md
index 4ac9317b01a..27fd1f48aec 100644
--- a/doc/api/graphql/sample_issue_boards.md
+++ b/doc/api/graphql/sample_issue_boards.md
@@ -1,3 +1,9 @@
+---
+stage: none
+group: unassigned
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
+---
+
# Identify issue boards with GraphQL
This page describes how you can use the GraphiQL explorer to identify
diff --git a/doc/api/group_activity_analytics.md b/doc/api/group_activity_analytics.md
index 90920d1b25c..38394c6412d 100644
--- a/doc/api/group_activity_analytics.md
+++ b/doc/api/group_activity_analytics.md
@@ -1,3 +1,9 @@
+---
+stage: none
+group: unassigned
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
+---
+
# Group Activity Analytics API
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/26460) in GitLab 12.9.
diff --git a/doc/api/group_badges.md b/doc/api/group_badges.md
index 43e1944226d..e13b9633da9 100644
--- a/doc/api/group_badges.md
+++ b/doc/api/group_badges.md
@@ -1,3 +1,9 @@
+---
+stage: none
+group: unassigned
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
+---
+
# Group badges API
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/17082) in GitLab 10.6.
diff --git a/doc/api/group_import_export.md b/doc/api/group_import_export.md
index 01d81eb62ac..dfd78e88233 100644
--- a/doc/api/group_import_export.md
+++ b/doc/api/group_import_export.md
@@ -1,3 +1,9 @@
+---
+stage: none
+group: unassigned
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
+---
+
# Group Import/Export API
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/20353) in GitLab 12.8.
diff --git a/doc/user/group/epics/manage_epics.md b/doc/user/group/epics/manage_epics.md
index c09032bffb2..a9a307dd89a 100644
--- a/doc/user/group/epics/manage_epics.md
+++ b/doc/user/group/epics/manage_epics.md
@@ -23,9 +23,9 @@ selected group. From your group page:
To create an epic from the epic list, in a group:
1. Go to **{epic}** **Epics**.
-1. Click **New epic**.
+1. Select **New epic**.
1. Enter a descriptive title.
-1. Click **Create epic**.
+1. Select **Create epic**.
### Access the New Epic form
@@ -33,8 +33,8 @@ To create an epic from the epic list, in a group:
There are two ways to get to the New Epic form and create an epic in the group you're in:
-- From an epic in your group, click **New Epic**.
-- From anywhere, in the top menu, click **plus** (**{plus-square}**) **> New epic**.
+- From an epic in your group, select **New Epic**.
+- From anywhere, in the top menu, select **plus** (**{plus-square}**) **> New epic**.
![New epic from an open epic](img/new_epic_from_groups_v13.2.png)
@@ -63,13 +63,13 @@ After you create an epic, you can edit change the following details:
To edit an epic's title or description:
-1. Click the **Edit title and description** **{pencil}** button.
+1. Select the **Edit title and description** **{pencil}** button.
1. Make your changes.
-1. Click **Save changes**.
+1. Select **Save changes**.
To edit an epics' start date, due date, or labels:
-1. Click **Edit** next to each section in the epic sidebar.
+1. Select **Edit** next to each section in the epic sidebar.
1. Select the dates or labels for your epic.
## Bulk-edit epics
@@ -82,7 +82,7 @@ You can edit multiple epics at once. To learn how to do it, visit
NOTE: **Note:**
To delete an epic, you need to be an [Owner](../../permissions.md#group-members-permissions) of a group/subgroup.
-When editing the description of an epic, click the **Delete** button to delete the epic.
+When editing the description of an epic, select the **Delete** button to delete the epic.
A modal appears to confirm your action.
Deleting an epic releases all existing issues from their associated epic in the system.
@@ -92,7 +92,7 @@ Deleting an epic releases all existing issues from their associated epic in the
Whenever you decide that there is no longer need for that epic,
close the epic by:
-- Clicking the **Close epic** button.
+- Selecting the **Close epic** button.
![close epic - button](img/button_close_epic.png)
@@ -129,7 +129,7 @@ that of Issues and Merge Requests) based on following parameters:
![epics search](img/epics_search.png)
-To search, go to the list of epics and click the field **Search or filter results**.
+To search, go to the list of epics and select the field **Search or filter results**.
It will display a dropdown menu, from which you can add an author. You can also enter plain
text to search by epic title or description. When done, press <kbd>Enter</kbd> on your
keyboard to filter the list.
@@ -168,7 +168,7 @@ To make an epic confidential:
### Add a new issue to an epic
-You can add an existing issue to an epic, or, create a new issue that's
+You can add an existing issue to an epic, or create a new issue that's
automatically added to the epic.
#### Add an existing issue to an epic
@@ -183,15 +183,15 @@ current parent.
To add a new issue to an epic:
-1. Click the **Add** dropdown button.
-1. Click **Add a new issue**.
+1. On the epic's page, under **Epics and Issues**, select the **Add** dropdown button.
+1. Select **Add an existing issue**.
1. Identify the issue to be added, using either of the following methods:
- Paste the link of the issue.
- Search for the desired issue by entering part of the issue's title, then selecting the desired
match (introduced in [GitLab 12.5](https://gitlab.com/gitlab-org/gitlab/-/issues/9126)).
If there are multiple issues to be added, press <kbd>Spacebar</kbd> and repeat this step.
-1. Click **Add**.
+1. Select **Add**.
#### Create an issue from an epic
@@ -202,11 +202,11 @@ while dividing work into smaller parts.
To create an issue from an epic:
-1. On the epic's page, under **Epics and Issues**, click the **Add** dropdown button and select
- **Create new issue**.
+1. On the epic's page, under **Epics and Issues**, select the **Add** dropdown button.
+1. Select **Add a new issue**.
1. Under **Title**, enter the title for the new issue.
1. From the **Project** dropdown, select the project in which the issue should be created.
-1. Click **Create issue**.
+1. Select **Create issue**.
### Remove an issue from an epic
@@ -215,9 +215,9 @@ After you remove an issue from an epic, the issue will no longer be associated w
To remove an issue from an epic:
-1. Click the **Remove** (**{close}**) button next to the issue you want to remove.
+1. Select the **Remove** (**{close}**) button next to the issue you want to remove.
The **Remove issue** warning appears.
-1. Click **Remove**.
+1. Select **Remove**.
![List of issues assigned to an epic](img/issue_list_v13_1.png)
@@ -285,15 +285,15 @@ For more on epic templates, see [Epic Templates - Repeatable sets of issues](htt
To add a child epic to an epic:
-1. Click the **Add** dropdown button.
-1. Click **Add a new epic**.
+1. Select the **Add** dropdown button.
+1. Select **Add a new epic**.
1. Identify the epic to be added, using either of the following methods:
- Paste the link of the epic.
- Search for the desired issue by entering part of the epic's title, then selecting the desired
match (introduced in [GitLab 12.5](https://gitlab.com/gitlab-org/gitlab/-/issues/9126)).
If there are multiple epics to be added, press <kbd>Spacebar</kbd> and repeat this step.
-1. Click **Add**.
+1. Select **Add**.
### Move child epics between epics
@@ -325,5 +325,5 @@ To reorder child epics assigned to an epic:
To remove a child epic from a parent epic:
-1. Click on the <kbd>x</kbd> button in the parent epic's list of epics.
-1. Click **Remove** in the **Remove epic** warning message.
+1. Select the <kbd>x</kbd> button in the parent epic's list of epics.
+1. Select **Remove** in the **Remove epic** warning message.
diff --git a/lib/api/api.rb b/lib/api/api.rb
index e6935d4e74a..358967c72d2 100644
--- a/lib/api/api.rb
+++ b/lib/api/api.rb
@@ -25,7 +25,8 @@ module API
Gitlab::GrapeLogging::Loggers::QueueDurationLogger.new,
Gitlab::GrapeLogging::Loggers::PerfLogger.new,
Gitlab::GrapeLogging::Loggers::CorrelationIdLogger.new,
- Gitlab::GrapeLogging::Loggers::ContextLogger.new
+ Gitlab::GrapeLogging::Loggers::ContextLogger.new,
+ Gitlab::GrapeLogging::Loggers::ContentLogger.new
]
allow_access_with_scope :api
diff --git a/lib/gitlab/ci/templates/Security/SAST.gitlab-ci.yml b/lib/gitlab/ci/templates/Security/SAST.gitlab-ci.yml
index 4418ff18d73..a51cb61da6d 100644
--- a/lib/gitlab/ci/templates/Security/SAST.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Security/SAST.gitlab-ci.yml
@@ -134,6 +134,7 @@ mobsf-android-sast:
name: "$SAST_ANALYZER_IMAGE"
variables:
SAST_ANALYZER_IMAGE: "$SECURE_ANALYZERS_PREFIX/mobsf:$SAST_ANALYZER_IMAGE_TAG"
+ MOBSF_API_KEY: key
rules:
- if: $SAST_DISABLED
when: never
@@ -152,6 +153,7 @@ mobsf-ios-sast:
name: "$SAST_ANALYZER_IMAGE"
variables:
SAST_ANALYZER_IMAGE: "$SECURE_ANALYZERS_PREFIX/mobsf:$SAST_ANALYZER_IMAGE_TAG"
+ MOBSF_API_KEY: key
rules:
- if: $SAST_DISABLED
when: never
diff --git a/lib/gitlab/etag_caching/middleware.rb b/lib/gitlab/etag_caching/middleware.rb
index 303e1a23e6b..81cfce6a3db 100644
--- a/lib/gitlab/etag_caching/middleware.rb
+++ b/lib/gitlab/etag_caching/middleware.rb
@@ -54,7 +54,13 @@ module Gitlab
add_instrument_for_cache_hit(status_code, route, request)
- [status_code, { 'ETag' => etag, 'X-Gitlab-From-Cache' => 'true' }, []]
+ new_headers = {
+ 'ETag' => etag,
+ 'X-Gitlab-From-Cache' => 'true',
+ ::Gitlab::Metrics::RequestsRackMiddleware::FEATURE_CATEGORY_HEADER => route.feature_category
+ }
+
+ [status_code, new_headers, []]
end
def track_cache_miss(if_none_match, cached_value_present, route)
diff --git a/lib/gitlab/etag_caching/router.rb b/lib/gitlab/etag_caching/router.rb
index 17d9cf08367..769ac2784d1 100644
--- a/lib/gitlab/etag_caching/router.rb
+++ b/lib/gitlab/etag_caching/router.rb
@@ -3,7 +3,7 @@
module Gitlab
module EtagCaching
class Router
- Route = Struct.new(:regexp, :name)
+ Route = Struct.new(:regexp, :name, :feature_category)
# We enable an ETag for every request matching the regex.
# To match a regex the path needs to match the following:
# - Don't contain a reserved word (expect for the words used in the
@@ -20,59 +20,73 @@ module Gitlab
ROUTES = [
Gitlab::EtagCaching::Router::Route.new(
%r(#{RESERVED_WORDS_PREFIX}/noteable/issue/\d+/notes\z),
- 'issue_notes'
+ 'issue_notes',
+ 'issue_tracking'
),
Gitlab::EtagCaching::Router::Route.new(
%r(#{RESERVED_WORDS_PREFIX}/noteable/merge_request/\d+/notes\z),
- 'merge_request_notes'
+ 'merge_request_notes',
+ 'code_review'
),
Gitlab::EtagCaching::Router::Route.new(
%r(#{RESERVED_WORDS_PREFIX}/issues/\d+/realtime_changes\z),
- 'issue_title'
+ 'issue_title',
+ 'issue_tracking'
),
Gitlab::EtagCaching::Router::Route.new(
%r(#{RESERVED_WORDS_PREFIX}/commit/\S+/pipelines\.json\z),
- 'commit_pipelines'
+ 'commit_pipelines',
+ 'continuous_integration'
),
Gitlab::EtagCaching::Router::Route.new(
%r(#{RESERVED_WORDS_PREFIX}/merge_requests/new\.json\z),
- 'new_merge_request_pipelines'
+ 'new_merge_request_pipelines',
+ 'continuous_integration'
),
Gitlab::EtagCaching::Router::Route.new(
%r(#{RESERVED_WORDS_PREFIX}/merge_requests/\d+/pipelines\.json\z),
- 'merge_request_pipelines'
+ 'merge_request_pipelines',
+ 'continuous_integration'
),
Gitlab::EtagCaching::Router::Route.new(
%r(#{RESERVED_WORDS_PREFIX}/pipelines\.json\z),
- 'project_pipelines'
+ 'project_pipelines',
+ 'continuous_integration'
),
Gitlab::EtagCaching::Router::Route.new(
%r(#{RESERVED_WORDS_PREFIX}/pipelines/\d+\.json\z),
- 'project_pipeline'
+ 'project_pipeline',
+ 'continuous_integration'
),
Gitlab::EtagCaching::Router::Route.new(
%r(#{RESERVED_WORDS_PREFIX}/builds/\d+\.json\z),
- 'project_build'
+ 'project_build',
+ 'continuous_integration'
),
Gitlab::EtagCaching::Router::Route.new(
%r(#{RESERVED_WORDS_PREFIX}/clusters/\d+/environments\z),
- 'cluster_environments'
+ 'cluster_environments',
+ 'continuous_delivery'
),
Gitlab::EtagCaching::Router::Route.new(
%r(#{RESERVED_WORDS_PREFIX}/environments\.json\z),
- 'environments'
+ 'environments',
+ 'continuous_delivery'
),
Gitlab::EtagCaching::Router::Route.new(
%r(#{RESERVED_WORDS_PREFIX}/import/github/realtime_changes\.json\z),
- 'realtime_changes_import_github'
+ 'realtime_changes_import_github',
+ 'importers'
),
Gitlab::EtagCaching::Router::Route.new(
%r(#{RESERVED_WORDS_PREFIX}/import/gitea/realtime_changes\.json\z),
- 'realtime_changes_import_gitea'
+ 'realtime_changes_import_gitea',
+ 'importers'
),
Gitlab::EtagCaching::Router::Route.new(
%r(#{RESERVED_WORDS_PREFIX}/merge_requests/\d+/cached_widget\.json\z),
- 'merge_request_widget'
+ 'merge_request_widget',
+ 'code_review'
)
].freeze
diff --git a/lib/gitlab/grape_logging/loggers/content_logger.rb b/lib/gitlab/grape_logging/loggers/content_logger.rb
new file mode 100644
index 00000000000..658953adc80
--- /dev/null
+++ b/lib/gitlab/grape_logging/loggers/content_logger.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module GrapeLogging
+ module Loggers
+ class ContentLogger < ::GrapeLogging::Loggers::Base
+ def parameters(request, _)
+ {
+ content_length: request.env['CONTENT_LENGTH'],
+ content_range: request.env['HTTP_CONTENT_RANGE']
+ }.compact
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/middleware/handle_null_bytes.rb b/lib/gitlab/middleware/handle_malformed_strings.rb
index c88dfb6ee0b..5fe3e6a1c73 100644
--- a/lib/gitlab/middleware/handle_null_bytes.rb
+++ b/lib/gitlab/middleware/handle_malformed_strings.rb
@@ -2,9 +2,9 @@
module Gitlab
module Middleware
- # There is no valid reason for a request to contain a null byte (U+0000)
+ # There is no valid reason for a request to contain a malformed string
# so just return HTTP 400 (Bad Request) if we receive one
- class HandleNullBytes
+ class HandleMalformedStrings
NULL_BYTE_REGEX = Regexp.new(Regexp.escape("\u0000")).freeze
attr_reader :app
@@ -14,18 +14,20 @@ module Gitlab
end
def call(env)
- return [400, {}, ["Bad Request"]] if request_has_null_byte?(env)
+ return [400, { 'Content-Type' => 'text/plain' }, ['Bad Request']] if request_contains_malformed_string?(env)
app.call(env)
end
private
- def request_has_null_byte?(request)
- return false if ENV['REJECT_NULL_BYTES'] == "1"
+ def request_contains_malformed_string?(request)
+ return false if ENV['DISABLE_REQUEST_VALIDATION'] == '1'
request = Rack::Request.new(request)
+ return true if string_malformed?(request.path)
+
request.params.values.any? do |value|
param_has_null_byte?(value)
end
@@ -39,7 +41,7 @@ module Gitlab
depth += 1
if value.respond_to?(:match)
- string_contains_null_byte?(value)
+ string_malformed?(value)
elsif value.respond_to?(:values)
value.values.any? do |hash_value|
param_has_null_byte?(hash_value, depth)
@@ -53,8 +55,11 @@ module Gitlab
end
end
- def string_contains_null_byte?(string)
+ def string_malformed?(string)
string.match?(NULL_BYTE_REGEX)
+ rescue ArgumentError
+ # If we're here, we caught a malformed string. Return true
+ true
end
end
end
diff --git a/spec/features/merge_request/user_suggests_changes_on_diff_spec.rb b/spec/features/merge_request/user_suggests_changes_on_diff_spec.rb
index 9268190c7e0..1e1888cd826 100644
--- a/spec/features/merge_request/user_suggests_changes_on_diff_spec.rb
+++ b/spec/features/merge_request/user_suggests_changes_on_diff_spec.rb
@@ -304,7 +304,7 @@ RSpec.describe 'User comments on a diff', :js do
wait_for_requests
end
- it 'suggestion is presented' do
+ it 'suggestion is presented', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/268240' do
page.within('.diff-discussions') do
expect(page).to have_button('Apply suggestion')
expect(page).to have_content('Suggested change')
diff --git a/spec/frontend/static_site_editor/components/edit_area_spec.js b/spec/frontend/static_site_editor/components/edit_area_spec.js
index 7e90b53dd07..8013e712558 100644
--- a/spec/frontend/static_site_editor/components/edit_area_spec.js
+++ b/spec/frontend/static_site_editor/components/edit_area_spec.js
@@ -15,6 +15,7 @@ import {
sourceContentHeaderObjYAML as headerSettings,
sourceContentBody as body,
returnUrl,
+ mounts,
} from '../mock_data';
jest.mock('~/static_site_editor/services/formatter', () => jest.fn(str => `${str} format-pass`));
@@ -31,6 +32,7 @@ describe('~/static_site_editor/components/edit_area.vue', () => {
title,
content,
returnUrl,
+ mounts,
savingChanges,
...propsData,
},
diff --git a/spec/frontend/static_site_editor/mock_data.js b/spec/frontend/static_site_editor/mock_data.js
index 0b08e290227..ce7c52e8277 100644
--- a/spec/frontend/static_site_editor/mock_data.js
+++ b/spec/frontend/static_site_editor/mock_data.js
@@ -67,3 +67,10 @@ export const images = new Map([
['path/to/image1.png', 'image1-content'],
['path/to/image2.png', 'image2-content'],
]);
+
+export const mounts = [
+ {
+ source: 'some/source/',
+ target: '',
+ },
+];
diff --git a/spec/frontend/static_site_editor/pages/home_spec.js b/spec/frontend/static_site_editor/pages/home_spec.js
index 2c69e884005..8fca8d0f2b9 100644
--- a/spec/frontend/static_site_editor/pages/home_spec.js
+++ b/spec/frontend/static_site_editor/pages/home_spec.js
@@ -23,6 +23,7 @@ import {
submitChangesError,
trackingCategory,
images,
+ mounts,
} from '../mock_data';
const localVue = createLocalVue();
@@ -41,6 +42,7 @@ describe('static_site_editor/pages/home', () => {
project,
username,
sourcePath,
+ mounts,
};
const hasSubmittedChangesMutationPayload = {
data: {
@@ -119,6 +121,7 @@ describe('static_site_editor/pages/home', () => {
it('provides source content, returnUrl, and isSavingChanges to the edit area', () => {
expect(findEditArea().props()).toMatchObject({
title,
+ mounts,
content,
returnUrl,
savingChanges: false,
diff --git a/spec/lib/gitlab/etag_caching/middleware_spec.rb b/spec/lib/gitlab/etag_caching/middleware_spec.rb
index 361b2329e15..45916e78532 100644
--- a/spec/lib/gitlab/etag_caching/middleware_spec.rb
+++ b/spec/lib/gitlab/etag_caching/middleware_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Gitlab::EtagCaching::Middleware do
+RSpec.describe Gitlab::EtagCaching::Middleware, :clean_gitlab_redis_shared_state do
let(:app) { double(:app) }
let(:middleware) { described_class.new(app) }
let(:app_status_code) { 200 }
@@ -17,10 +17,12 @@ RSpec.describe Gitlab::EtagCaching::Middleware do
mock_app_response
end
- it 'does not add ETag header' do
+ it 'does not add ETag headers' do
_, headers, _ = middleware.call(build_request(path, if_none_match))
expect(headers['ETag']).to be_nil
+ expect(headers['X-Gitlab-From-Cache']).to be_nil
+ expect(headers[::Gitlab::Metrics::RequestsRackMiddleware::FEATURE_CATEGORY_HEADER]).to be_nil
end
it 'passes status code from app' do
@@ -68,7 +70,7 @@ RSpec.describe Gitlab::EtagCaching::Middleware do
mock_value_in_store('123')
end
- it 'returns this value as header' do
+ it 'returns the correct headers' do
_, headers, _ = middleware.call(build_request(path, if_none_match))
expect(headers['ETag']).to eq 'W/"123"'
@@ -126,6 +128,13 @@ RSpec.describe Gitlab::EtagCaching::Middleware do
expect(status).to eq 304
end
+ it 'sets correct headers' do
+ _, headers, _ = middleware.call(build_request(path, if_none_match))
+
+ expect(headers).to include('X-Gitlab-From-Cache' => 'true',
+ ::Gitlab::Metrics::RequestsRackMiddleware::FEATURE_CATEGORY_HEADER => 'issue_tracking')
+ end
+
it_behaves_like 'sends a process_action.action_controller notification', 304
it 'returns empty body' do
diff --git a/spec/lib/gitlab/etag_caching/router_spec.rb b/spec/lib/gitlab/etag_caching/router_spec.rb
index 3e939e588ad..dbd9cc230f1 100644
--- a/spec/lib/gitlab/etag_caching/router_spec.rb
+++ b/spec/lib/gitlab/etag_caching/router_spec.rb
@@ -127,4 +127,12 @@ RSpec.describe Gitlab::EtagCaching::Router do
expect(result).to be_present
expect(result.name).to eq 'project_pipeline'
end
+
+ it 'has a valid feature category for every route', :aggregate_failures do
+ feature_categories = YAML.load_file(Rails.root.join('config', 'feature_categories.yml')).to_set
+
+ described_class::ROUTES.each do |route|
+ expect(feature_categories).to include(route.feature_category), "#{route.name} has a category of #{route.feature_category}, which is not valid"
+ end
+ end
end
diff --git a/spec/lib/gitlab/middleware/handle_malformed_strings_spec.rb b/spec/lib/gitlab/middleware/handle_malformed_strings_spec.rb
new file mode 100644
index 00000000000..6680720e403
--- /dev/null
+++ b/spec/lib/gitlab/middleware/handle_malformed_strings_spec.rb
@@ -0,0 +1,109 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require "rack/test"
+
+RSpec.describe Gitlab::Middleware::HandleMalformedStrings do
+ let(:null_byte) { "\u0000" }
+ let(:invalid_string) { "mal\xC0formed" }
+ let(:error_400) { [400, { 'Content-Type' => 'text/plain' }, ['Bad Request']] }
+ let(:app) { double(:app) }
+
+ subject { described_class.new(app) }
+
+ before do
+ allow(app).to receive(:call) do |args|
+ args
+ end
+ end
+
+ def env_for(params = {})
+ Rack::MockRequest.env_for('/', { params: params })
+ end
+
+ context 'in the URL' do
+ it 'rejects null bytes' do
+ # We have to create the env separately or Rack::MockRequest complains about invalid URI
+ env = env_for
+ env['PATH_INFO'] = "/someplace/witha#{null_byte}nullbyte"
+
+ expect(subject.call(env)).to eq error_400
+ end
+
+ it 'rejects malformed strings' do
+ # We have to create the env separately or Rack::MockRequest complains about invalid URI
+ env = env_for
+ env['PATH_INFO'] = "/someplace/with_an/#{invalid_string}"
+
+ expect(subject.call(env)).to eq error_400
+ end
+ end
+
+ context 'in params' do
+ shared_examples_for 'checks params' do
+ it 'rejects bad params in a top level param' do
+ env = env_for(name: "null#{problematic_input}byte")
+
+ expect(subject.call(env)).to eq error_400
+ end
+
+ it "rejects bad params for hashes with strings" do
+ env = env_for(name: { inner_key: "I am #{problematic_input} bad" })
+
+ expect(subject.call(env)).to eq error_400
+ end
+
+ it "rejects bad params for arrays with strings" do
+ env = env_for(name: ["I am #{problematic_input} bad"])
+
+ expect(subject.call(env)).to eq error_400
+ end
+
+ it "rejects bad params for arrays containing hashes with string values" do
+ env = env_for(name: [
+ {
+ inner_key: "I am #{problematic_input} bad"
+ }
+ ])
+
+ expect(subject.call(env)).to eq error_400
+ end
+
+ it "gives up and does not reject too deeply nested params" do
+ env = env_for(name: [
+ {
+ inner_key: { deeper_key: [{ hash_inside_array_key: "I am #{problematic_input} bad" }] }
+ }
+ ])
+
+ expect(subject.call(env)).not_to eq error_400
+ end
+ end
+
+ context 'with null byte' do
+ it_behaves_like 'checks params' do
+ let(:problematic_input) { null_byte }
+ end
+ end
+
+ context 'with malformed strings' do
+ it_behaves_like 'checks params' do
+ let(:problematic_input) { invalid_string }
+ end
+ end
+ end
+
+ context 'without problematic input' do
+ it "does not error for strings" do
+ env = env_for(name: "safe name")
+
+ expect(subject.call(env)).not_to eq error_400
+ end
+
+ it "does not error with no params" do
+ env = env_for
+
+ expect(subject.call(env)).not_to eq error_400
+ end
+ end
+end
diff --git a/spec/lib/gitlab/middleware/handle_null_bytes_spec.rb b/spec/lib/gitlab/middleware/handle_null_bytes_spec.rb
deleted file mode 100644
index 76a5174817e..00000000000
--- a/spec/lib/gitlab/middleware/handle_null_bytes_spec.rb
+++ /dev/null
@@ -1,88 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require "rack/test"
-
-RSpec.describe Gitlab::Middleware::HandleNullBytes do
- let(:null_byte) { "\u0000" }
- let(:error_400) { [400, {}, ["Bad Request"]] }
- let(:app) { double(:app) }
-
- subject { described_class.new(app) }
-
- before do
- allow(app).to receive(:call) do |args|
- args
- end
- end
-
- def env_for(params = {})
- Rack::MockRequest.env_for('/', { params: params })
- end
-
- context 'with null bytes in params' do
- it 'rejects null bytes in a top level param' do
- env = env_for(name: "null#{null_byte}byte")
-
- expect(subject.call(env)).to eq error_400
- end
-
- it "responds with 400 BadRequest for hashes with strings" do
- env = env_for(name: { inner_key: "I am #{null_byte} bad" })
-
- expect(subject.call(env)).to eq error_400
- end
-
- it "responds with 400 BadRequest for arrays with strings" do
- env = env_for(name: ["I am #{null_byte} bad"])
-
- expect(subject.call(env)).to eq error_400
- end
-
- it "responds with 400 BadRequest for arrays containing hashes with string values" do
- env = env_for(name: [
- {
- inner_key: "I am #{null_byte} bad"
- }
- ])
-
- expect(subject.call(env)).to eq error_400
- end
-
- it "gives up and does not 400 with too deeply nested params" do
- env = env_for(name: [
- {
- inner_key: { deeper_key: [{ hash_inside_array_key: "I am #{null_byte} bad" }] }
- }
- ])
-
- expect(subject.call(env)).not_to eq error_400
- end
- end
-
- context 'without null bytes in params' do
- it "does not respond with a 400 for strings" do
- env = env_for(name: "safe name")
-
- expect(subject.call(env)).not_to eq error_400
- end
-
- it "does not respond with a 400 with no params" do
- env = env_for
-
- expect(subject.call(env)).not_to eq error_400
- end
- end
-
- context 'when disabled via env flag' do
- before do
- stub_env('REJECT_NULL_BYTES', '1')
- end
-
- it 'does not respond with a 400 no matter what' do
- env = env_for(name: "null#{null_byte}byte")
-
- expect(subject.call(env)).not_to eq error_400
- end
- end
-end
diff --git a/spec/requests/user_sends_malformed_strings_spec.rb b/spec/requests/user_sends_malformed_strings_spec.rb
new file mode 100644
index 00000000000..b6eda9159bc
--- /dev/null
+++ b/spec/requests/user_sends_malformed_strings_spec.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'User sends malformed strings as params' do
+ let(:null_byte) { "\u0000" }
+ let(:invalid_string) { "mal\xC0formed" }
+
+ it 'raises a 400 error with a null byte' do
+ post '/nonexistent', params: { a: "A #{null_byte} nasty string" }
+
+ expect(response).to have_gitlab_http_status(:bad_request)
+ end
+
+ it 'raises a 400 error with an invalid string' do
+ post '/nonexistent', params: { a: "A #{invalid_string} nasty string" }
+
+ expect(response).to have_gitlab_http_status(:bad_request)
+ end
+end
diff --git a/spec/requests/user_sends_null_bytes_spec.rb b/spec/requests/user_sends_null_bytes_spec.rb
deleted file mode 100644
index 1ddfad40996..00000000000
--- a/spec/requests/user_sends_null_bytes_spec.rb
+++ /dev/null
@@ -1,14 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe 'User sends null bytes as params' do
- let(:null_byte) { "\u0000" }
-
- it 'raises a 400 error' do
- post '/nonexistent', params: { a: "A #{null_byte} nasty string" }
-
- expect(response).to have_gitlab_http_status(:bad_request)
- expect(response.body).to eq('Bad Request')
- end
-end