Skip to content

Commit

Permalink
fix(flags): Make sure regex matching matches strings (#20557)
Browse files Browse the repository at this point in the history
  • Loading branch information
neilkakkar authored Feb 26, 2024
1 parent a85b806 commit eca7028
Show file tree
Hide file tree
Showing 5 changed files with 144 additions and 5 deletions.
5 changes: 2 additions & 3 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion posthog/models/property/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -480,7 +480,7 @@ def prop_filter_json_extract(
params,
)
elif operator in ("regex", "not_regex"):
if not is_valid_regex(prop.value):
if not is_valid_regex(str(prop.value)):
# If OR'ing, shouldn't be a problem since nothing will match this specific clause
return f"{property_operator} 1 = 2", {}

Expand Down
2 changes: 1 addition & 1 deletion posthog/queries/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,7 @@ def property_to_Q(
return Q(**{f"{column}__{property.key}__isnull": False})
if property.operator == "is_not_set":
return Q(**{f"{column}__{property.key}__isnull": True})
if property.operator in ("regex", "not_regex") and not is_valid_regex(value):
if property.operator in ("regex", "not_regex") and not is_valid_regex(str(value)):
# Return no data for invalid regexes
return Q(pk=-1)
if isinstance(property.operator, str) and property.operator.startswith("not_"):
Expand Down
106 changes: 106 additions & 0 deletions posthog/test/__snapshots__/test_feature_flag.ambr
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,112 @@
AND "posthog_person"."team_id" = 2)
'''
# ---
# name: TestFeatureFlagMatcher.test_invalid_regex_match_flag
'''
SELECT "posthog_team"."id",
"posthog_team"."uuid",
"posthog_team"."organization_id",
"posthog_team"."api_token",
"posthog_team"."app_urls",
"posthog_team"."name",
"posthog_team"."slack_incoming_webhook",
"posthog_team"."created_at",
"posthog_team"."updated_at",
"posthog_team"."anonymize_ips",
"posthog_team"."completed_snippet_onboarding",
"posthog_team"."has_completed_onboarding_for",
"posthog_team"."ingested_event",
"posthog_team"."autocapture_opt_out",
"posthog_team"."autocapture_exceptions_opt_in",
"posthog_team"."autocapture_exceptions_errors_to_ignore",
"posthog_team"."session_recording_opt_in",
"posthog_team"."session_recording_sample_rate",
"posthog_team"."session_recording_minimum_duration_milliseconds",
"posthog_team"."session_recording_linked_flag",
"posthog_team"."session_recording_network_payload_capture_config",
"posthog_team"."session_replay_config",
"posthog_team"."capture_console_log_opt_in",
"posthog_team"."capture_performance_opt_in",
"posthog_team"."surveys_opt_in",
"posthog_team"."session_recording_version",
"posthog_team"."signup_token",
"posthog_team"."is_demo",
"posthog_team"."access_control",
"posthog_team"."week_start_day",
"posthog_team"."inject_web_apps",
"posthog_team"."test_account_filters",
"posthog_team"."test_account_filters_default_checked",
"posthog_team"."path_cleaning_filters",
"posthog_team"."timezone",
"posthog_team"."data_attributes",
"posthog_team"."person_display_name_properties",
"posthog_team"."live_events_columns",
"posthog_team"."recording_domains",
"posthog_team"."primary_dashboard_id",
"posthog_team"."extra_settings",
"posthog_team"."correlation_config",
"posthog_team"."session_recording_retention_period_days",
"posthog_team"."plugins_opt_in",
"posthog_team"."opt_out_capture",
"posthog_team"."event_names",
"posthog_team"."event_names_with_usage",
"posthog_team"."event_properties",
"posthog_team"."event_properties_with_usage",
"posthog_team"."event_properties_numerical",
"posthog_team"."external_data_workspace_id",
"posthog_team"."external_data_workspace_last_synced_at"
FROM "posthog_team"
WHERE "posthog_team"."id" = 2
LIMIT 21
'''
# ---
# name: TestFeatureFlagMatcher.test_invalid_regex_match_flag.1
'''
SELECT "posthog_featureflag"."id",
"posthog_featureflag"."key",
"posthog_featureflag"."name",
"posthog_featureflag"."filters",
"posthog_featureflag"."rollout_percentage",
"posthog_featureflag"."team_id",
"posthog_featureflag"."created_by_id",
"posthog_featureflag"."created_at",
"posthog_featureflag"."deleted",
"posthog_featureflag"."active",
"posthog_featureflag"."rollback_conditions",
"posthog_featureflag"."performed_rollback",
"posthog_featureflag"."ensure_experience_continuity",
"posthog_featureflag"."usage_dashboard_id",
"posthog_featureflag"."has_enriched_analytics"
FROM "posthog_featureflag"
WHERE ("posthog_featureflag"."active"
AND NOT "posthog_featureflag"."deleted"
AND "posthog_featureflag"."team_id" = 2)
'''
# ---
# name: TestFeatureFlagMatcher.test_invalid_regex_match_flag.2
'''
SELECT (("posthog_person"."properties" ->> 'email')::text ~ '["[email protected]"]'
AND "posthog_person"."properties" ? 'email'
AND NOT (("posthog_person"."properties" -> 'email') = 'null')) AS "flag_X_condition_0"
FROM "posthog_person"
INNER JOIN "posthog_persondistinctid" ON ("posthog_person"."id" = "posthog_persondistinctid"."person_id")
WHERE ("posthog_persondistinctid"."distinct_id" = '307'
AND "posthog_persondistinctid"."team_id" = 2
AND "posthog_person"."team_id" = 2)
'''
# ---
# name: TestFeatureFlagMatcher.test_invalid_regex_match_flag.3
'''
SELECT (("posthog_person"."properties" ->> 'email')::text ~ '["[email protected]"]'
AND "posthog_person"."properties" ? 'email'
AND NOT (("posthog_person"."properties" -> 'email') = 'null')) AS "flag_X_condition_0"
FROM "posthog_person"
INNER JOIN "posthog_persondistinctid" ON ("posthog_person"."id" = "posthog_persondistinctid"."person_id")
WHERE ("posthog_persondistinctid"."distinct_id" = 'another_id'
AND "posthog_persondistinctid"."team_id" = 2
AND "posthog_person"."team_id" = 2)
'''
# ---
# name: TestFeatureFlagMatcher.test_multiple_flags
'''
SELECT "posthog_grouptypemapping"."id",
Expand Down
34 changes: 34 additions & 0 deletions posthog/test/test_feature_flag.py
Original file line number Diff line number Diff line change
Expand Up @@ -763,6 +763,40 @@ def test_blank_flag(self):
FeatureFlagMatch(True, None, FeatureFlagMatchReason.CONDITION_MATCH, 0),
)

@snapshot_postgres_queries
def test_invalid_regex_match_flag(self):
Person.objects.create(
team=self.team,
distinct_ids=["307"],
properties={
"email": '"[email protected]"',
},
)
feature_flag = self.create_feature_flag(
filters={
"groups": [
{
"properties": [
{
"key": "email",
"value": '["[email protected]"]',
"operator": "regex",
"type": "person",
}
]
}
]
}
)
self.assertEqual(
FeatureFlagMatcher([feature_flag], "307").get_match(feature_flag),
FeatureFlagMatch(True, None, FeatureFlagMatchReason.CONDITION_MATCH, 0),
)
self.assertEqual(
FeatureFlagMatcher([feature_flag], "another_id").get_match(feature_flag),
FeatureFlagMatch(False, None, FeatureFlagMatchReason.NO_CONDITION_MATCH, 0),
)

def test_coercion_of_strings_and_numbers(self):
Person.objects.create(
team=self.team,
Expand Down

0 comments on commit eca7028

Please sign in to comment.