Page Menu
Home
WickedGov Phorge
Search
Configure Global Search
Log In
Files
F1425941
Validator.php
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
Validator.php
View Options
<?php
namespace
Cite
;
use
MediaWiki\Parser\Sanitizer
;
use
StatusValue
;
/**
* Context-aware, detailed validation of the arguments and content of a <ref> tag.
*
* @license GPL-2.0-or-later
*/
class
Validator
{
private
ReferenceStack
$referenceStack
;
private
?
string
$inReferencesGroup
;
private
bool
$isSectionPreview
;
private
bool
$isExtendsEnabled
;
/**
* @param ReferenceStack $referenceStack
* @param string|null $inReferencesGroup Group name of the <references> context to consider
* during validation. Null if we are currently not in a <references> context.
* @param bool $isSectionPreview Validation is relaxed when previewing parts of a page
* @param bool $isExtendsEnabled Temporary feature flag
*/
public
function
__construct
(
ReferenceStack
$referenceStack
,
?
string
$inReferencesGroup
=
null
,
bool
$isSectionPreview
=
false
,
bool
$isExtendsEnabled
=
false
)
{
$this
->
referenceStack
=
$referenceStack
;
$this
->
inReferencesGroup
=
$inReferencesGroup
;
$this
->
isSectionPreview
=
$isSectionPreview
;
$this
->
isExtendsEnabled
=
$isExtendsEnabled
;
}
public
function
validateRef
(
?
string
$text
,
string
$group
,
?
string
$name
,
?
string
$extends
,
?
string
$follow
,
?
string
$dir
):
StatusValue
{
if
(
ctype_digit
(
(
string
)
$name
)
||
ctype_digit
(
(
string
)
$extends
)
||
ctype_digit
(
(
string
)
$follow
)
)
{
// Numeric names mess up the resulting id's, potentially producing
// duplicate id's in the XHTML. The Right Thing To Do
// would be to mangle them, but it's not really high-priority
// (and would produce weird id's anyway).
return
StatusValue
::
newFatal
(
'cite_error_ref_numeric_key'
);
}
if
(
$extends
)
{
// Temporary feature flag until mainstreamed, see T236255
if
(
!
$this
->
isExtendsEnabled
)
{
return
StatusValue
::
newFatal
(
'cite_error_ref_too_many_keys'
);
}
$groupRefs
=
$this
->
referenceStack
->
getGroupRefs
(
$group
);
// @phan-suppress-next-line PhanTypeMismatchDimFetchNullable false positive
if
(
isset
(
$groupRefs
[
$name
]
)
&&
!
isset
(
$groupRefs
[
$name
]->
extends
)
)
{
// T242141: A top-level <ref> can't be changed into a sub-reference
return
StatusValue
::
newFatal
(
'cite_error_references_duplicate_key'
,
$name
);
}
elseif
(
isset
(
$groupRefs
[
$extends
]->
extends
)
)
{
// A sub-reference can not be extended a second time (no nesting)
return
StatusValue
::
newFatal
(
'cite_error_ref_nested_extends'
,
$extends
,
$groupRefs
[
$extends
]->
extends
);
}
}
if
(
$follow
&&
(
$name
||
$extends
)
)
{
return
StatusValue
::
newFatal
(
'cite_error_ref_follow_conflicts'
);
}
if
(
$dir
!==
null
&&
$dir
!==
'rtl'
&&
$dir
!==
'ltr'
)
{
return
StatusValue
::
newFatal
(
'cite_error_ref_invalid_dir'
,
$dir
);
}
return
$this
->
inReferencesGroup
===
null
?
$this
->
validateRefOutsideOfReferenceList
(
$text
,
$name
)
:
$this
->
validateRefInReferenceList
(
$text
,
$group
,
$name
);
}
private
function
validateRefOutsideOfReferenceList
(
?
string
$text
,
?
string
$name
):
StatusValue
{
if
(
!
$name
)
{
if
(
$text
===
null
)
{
// Completely empty ref like <ref /> is forbidden.
return
StatusValue
::
newFatal
(
'cite_error_ref_no_key'
);
}
elseif
(
trim
(
$text
)
===
''
)
{
// Must have content or reuse another ref by name.
return
StatusValue
::
newFatal
(
'cite_error_ref_no_input'
);
}
}
if
(
$text
!==
null
&&
preg_match
(
'/<ref(erences)?
\b
[^>]*+>/i'
,
preg_replace
(
'#<(
\w
++)[^>]*+>.*?</
\1\s
*>|<!--.*?-->#s'
,
''
,
$text
)
)
)
{
// (bug T8199) This most likely implies that someone left off the
// closing </ref> tag, which will cause the entire article to be
// eaten up until the next <ref>. So we bail out early instead.
// The fancy regex above first tries chopping out anything that
// looks like a comment or SGML tag, which is a crude way to avoid
// false alarms for <nowiki>, <pre>, etc.
//
// Possible improvement: print the warning, followed by the contents
// of the <ref> tag. This way no part of the article will be eaten
// even temporarily.
return
StatusValue
::
newFatal
(
'cite_error_included_ref'
);
}
return
StatusValue
::
newGood
();
}
private
function
validateRefInReferenceList
(
?
string
$text
,
string
$group
,
?
string
$name
):
StatusValue
{
if
(
$group
!==
$this
->
inReferencesGroup
)
{
// <ref> and <references> have conflicting group attributes.
return
StatusValue
::
newFatal
(
'cite_error_references_group_mismatch'
,
Sanitizer
::
safeEncodeAttribute
(
$group
)
);
}
if
(
!
$name
)
{
// <ref> calls inside <references> must be named
return
StatusValue
::
newFatal
(
'cite_error_references_no_key'
);
}
if
(
$text
===
null
||
trim
(
$text
)
===
''
)
{
// <ref> called in <references> has no content.
return
StatusValue
::
newFatal
(
'cite_error_empty_references_define'
,
Sanitizer
::
safeEncodeAttribute
(
$name
),
Sanitizer
::
safeEncodeAttribute
(
$group
)
);
}
// Section previews are exempt from some rules.
if
(
!
$this
->
isSectionPreview
)
{
$groupRefs
=
$this
->
referenceStack
->
getGroupRefs
(
$group
);
if
(
!
isset
(
$groupRefs
[
$name
]
)
)
{
// No such named ref exists in this group.
return
StatusValue
::
newFatal
(
'cite_error_references_missing_key'
,
Sanitizer
::
safeEncodeAttribute
(
$name
)
);
}
}
return
StatusValue
::
newGood
();
}
}
File Metadata
Details
Attached
Mime Type
text/x-php
Expires
Sat, May 16, 12:16 (1 d, 1 h)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
49/07/9e7eaef582c9dbb141bb20d858dd
Default Alt Text
Validator.php (5 KB)
Attached To
Mode
rMWPROD MediaWiki Production
Attached
Detach File
Event Timeline
Log In to Comment