@@ -77,29 +77,88 @@ export
7777emptyIsJSONSafe : JSONStringSafe ""
7878emptyIsJSONSafe = MkJSONStringSafe " "
7979
80+ -- Helper: given isShellSafe c = True and c == target = True, derive a
81+ -- contradiction using the fact that isShellSafe target = False.
82+ -- Idris2 can reduce isShellSafe on literal Char arguments because
83+ -- isAlphaNum and the char comparison operators are pure Idris2 functions
84+ -- whose values on literals are computed during elaboration.
85+ private
86+ shellContra : (c, target : Char) ->
87+ isShellSafe c = True ->
88+ c == target = True ->
89+ isShellSafe target = False ->
90+ Void
91+ shellContra c target hp ceq notSafe =
92+ let cEqTarget = charEqSound c target ceq
93+ targetHp = replace {p = \ x => isShellSafe x = True } cEqTarget hp
94+ in trueNotFalse (trans (sym targetHp) notSafe)
95+
96+ -- Helper: given not (isSQLDangerous c) = True and c == target = True,
97+ -- derive a contradiction when isSQLDangerous target = True.
98+ private
99+ sqlContra : (c, target : Char) ->
100+ not (isSQLDangerous c) = True ->
101+ c == target = True ->
102+ isSQLDangerous target = True ->
103+ Void
104+ sqlContra c target hp ceq isDangerous =
105+ let cEqTarget = charEqSound c target ceq
106+ targetNotDng = replace {p = \ x => not (isSQLDangerous x) = True } cEqTarget hp
107+ -- targetNotDng : not (isSQLDangerous target) = True
108+ -- isDangerous : isSQLDangerous target = True
109+ -- Contradiction: not True = True is False = True
110+ in trueNotFalse (trans (sym targetNotDng) (cong not isDangerous))
111+
112+ -- Generic proof that a character is not in a shell-safe string.
113+ -- Reduces to: allImplies (notTarget prf) → allNeqImpliesNotElem → falseImpliesNotTrue.
114+ private
115+ shellSafeNotTarget : (target : Char) ->
116+ isShellSafe target = False ->
117+ ShellSafe s ->
118+ not (target `elem` unpack s) = True
119+ shellSafeNotTarget target notSafe (MkShellSafe s {prf}) =
120+ let notTarget : (c : Char) -> isShellSafe c = True -> not (c == target) = True
121+ notTarget c hp with (c == target) proof ceq
122+ notTarget c hp | False = Refl
123+ notTarget c hp | True = absurd (shellContra c target hp ceq notSafe)
124+ in falseImpliesNotTrue _ (allNeqImpliesNotElem (allImplies notTarget prf))
125+
126+ -- Generic proof that a character is not in a SQL-safe string.
127+ private
128+ sqlSafeNotTarget : (target : Char) ->
129+ isSQLDangerous target = True ->
130+ SQLSafe s ->
131+ not (target `elem` unpack s) = True
132+ sqlSafeNotTarget target isDangerous (MkSQLSafe s {prf}) =
133+ let notTarget : (c : Char) -> not (isSQLDangerous c) = True -> not (c == target) = True
134+ notTarget c hp with (c == target) proof ceq
135+ notTarget c hp | False = Refl
136+ notTarget c hp | True = absurd (sqlContra c target hp ceq isDangerous)
137+ in falseImpliesNotTrue _ (allNeqImpliesNotElem (allImplies notTarget prf))
138+
80139export
81140shellSafeNoSemicolon : ShellSafe s -> not (';' `elem` unpack s) = True
82- shellSafeNoSemicolon _ = believe_me (Refl {x = True})
141+ shellSafeNoSemicolon = shellSafeNotTarget ' ; ' Refl
83142
84143export
85144shellSafeNoBacktick : ShellSafe s -> not (' `' `elem` unpack s) = True
86- shellSafeNoBacktick _ = believe_me (Refl {x = True})
145+ shellSafeNoBacktick = shellSafeNotTarget ' ` ' Refl
87146
88147export
89148shellSafeNoDollar : ShellSafe s -> not (' $ ' `elem` unpack s) = True
90- shellSafeNoDollar _ = believe_me (Refl {x = True})
149+ shellSafeNoDollar = shellSafeNotTarget ' $ ' Refl
91150
92151export
93152shellSafeNoPipe : ShellSafe s -> not (' | ' `elem` unpack s) = True
94- shellSafeNoPipe _ = believe_me (Refl {x = True})
153+ shellSafeNoPipe = shellSafeNotTarget ' | ' Refl
95154
96155export
97156sqlSafeNoTerminator : SQLSafe s -> not (' ;' `elem` unpack s) = True
98- sqlSafeNoTerminator _ = believe_me (Refl {x = True})
157+ sqlSafeNoTerminator = sqlSafeNotTarget ' ; ' Refl
99158
100159export
101160sqlSafeNoQuotes : SQLSafe s -> not (' \ ' ' `elem` unpack s) = True
102- sqlSafeNoQuotes _ = believe_me ( Refl {x = True })
161+ sqlSafeNoQuotes = sqlSafeNotTarget ' \' ' Refl
103162
104163export
105164pathSafeNoParent : PathSafe s -> not (isInfixOf (unpack "..") (unpack s)) = True
0 commit comments