@prefix sioc: <http://rdfs.org/sioc/ns#> .
@prefix dc: <http://purl.org/dc/elements/1.1/> .
@prefix dcterms: <http://purl.org/dc/terms/> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix content: <http://purl.org/rss/1.0/modules/content/> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .

<https://lhero.org/?post_type=lh-portfolio&#038;p=147062>
  a sioc:Post ;
  dc:title "PCP notes (accepted false positives)" ;
  dcterms:identifier 147062 ;
  dc:modified "2026-09-05T12:13:46Z"^^xsd:dateTime ;
  dc:created "2026-09-05T12:13:46Z"^^xsd:dateTime ;
  sioc:link <https://lhero.org/portfolio/lh-polls/pcp-notes-accepted-false-positives/> ;
  sioc:has_creator <https://lhero.org/author/1/#account> ;
  sioc:has_container <https://lhero.org/#posts> ;
  content:encoded """<p>The following are known Plugin Check (PCP) false positives, documented rather than suppressed with phpcs:ignore (except where a genuine fix using $wpdb-&gt;prepare()&#8217;s %i identifier placeholder was possible instead — see 1.0.11 changelog).</p>
<h3>WordPress.DB.DirectDatabaseQuery / NoCaching (class-lh-polls-db.php)</h3>
<p>All queries operate on custom tables (lh_poll_options, lh_poll_votes) with no WP API wrapper — direct $wpdb queries are correct. The class implements its own full transient caching layer via flush_poll_cache(); PCP cannot statically trace this.</p>
<h3>WordPress.Security.EscapeOutput.OutputNotEscaped on $avatar (class-lh-polls-votes-metabox.php)</h3>
<p>$avatar is the return value of bp_core_fetch_avatar() with &#8216;html&#8217; =&gt; true — the BuddyPress equivalent of get_avatar(), returning trusted internally-generated HTML that cannot be passed through an escaping function without corruption.</p>
<h3>WordPress.Security.NonceVerification in validate_poll_options (class-lh-polls-post-types.php)</h3>
<p>Fires via wp_insert_post_data before the post is saved. The nonce is verified in each metabox&#8217;s own save() method (via the shared should_save_poll_meta() guard), processing the same POST request — PCP cannot trace nonce verification across separate hook callbacks.</p>
<h3>WordPress.Security.NonceVerification.Recommended on feedback $_GET params</h3>
<p>lh_poll_msg and lh_poll_id query parameters are set by the plugin itself as part of a post-vote redirect, used only to display a read-only feedback message — no state change occurs. A nonce on a redirect parameter would expire immediately.</p>
<h3>WordPress.Security.EscapeOutput.OutputNotEscaped on $this-&gt;render_poll_markup(&#8230;) / poll_js_tag() (class-lh-polls-embed.php)</h3>
<p>Both methods build their return values entirely from esc_html(), esc_attr(), esc_url(), esc_textarea(), wp_nonce_field(), and wp_json_encode() with JSON_HEX_TAG/JSON_HEX_AMP — every dynamic value is escaped at the point of output within those methods. PCP cannot trace escaping through a method&#8217;s internal implementation.</p>
<h3>WordPress.WP.EnqueuedResources.NonEnqueuedStylesheet / NonEnqueuedScript (class-lh-polls-embed.php, serve_poll_document)</h3>
<p>The embed view (is_embed()) is a complete self-contained HTML document output directly via template_redirect + exit — it never calls wp_head()/wp_footer(), so wp_enqueue_style()/wp_enqueue_script() would never print. This is the intentional zero-theme-dependency design for the embed view. The standalone singular view (filter_the_content) does use wp_enqueue_style() correctly.</p>
<h3>WordPress.Security.ValidatedSanitizedInput.InputNotSanitized on $_GET[&#8216;redirect&#8217;]</h3>
<p>Passed through esc_url_raw( urldecode( wp_unslash( $_GET[&#8216;redirect&#8217;] ) ) ). PCP cannot trace sanitisation through urldecode().</p>
<h3>WordPress.Security.NonceVerification in LH_Polls_Voting::handle_form_post / process_vote / process_change_vote</h3>
<p>The nonce (lh_poll_nonce) is verified once at the top of handle_form_post() via wp_verify_nonce() before any $_POST data is processed. process_vote() and process_change_vote() are private methods called only after this check succeeds; PCP flags each method independently and cannot trace the call chain.</p>
"""^^rdf:XMLLiteral ;
  sioc:content """The following are known Plugin Check (PCP) false positives, documented rather than suppressed with phpcs:ignore (except where a genuine fix using $wpdb-&gt;prepare()&#8217;s %i identifier placeholder was possible instead — see 1.0.11 changelog).
WordPress.DB.DirectDatabaseQuery / NoCaching (class-lh-polls-db.php)
All queries operate on custom tables (lh_poll_options, lh_poll_votes) with no WP API wrapper — direct $wpdb queries are correct. The class implements its own full transient caching layer via flush_poll_cache(); PCP cannot statically trace this.
WordPress.Security.EscapeOutput.OutputNotEscaped on $avatar (class-lh-polls-votes-metabox.php)
$avatar is the return value of bp_core_fetch_avatar() with &#8216;html&#8217; =&gt; true — the BuddyPress equivalent of get_avatar(), returning trusted internally-generated HTML that cannot be passed through an escaping function without corruption.
WordPress.Security.NonceVerification in validate_poll_options (class-lh-polls-post-types.php)
Fires via wp_insert_post_data before the post is saved. The nonce is verified in each metabox&#8217;s own save() method (via the shared should_save_poll_meta() guard), processing the same POST request — PCP cannot trace nonce verification across separate hook callbacks.
WordPress.Security.NonceVerification.Recommended on feedback $_GET params
lh_poll_msg and lh_poll_id query parameters are set by the plugin itself as part of a post-vote redirect, used only to display a read-only feedback message — no state change occurs. A nonce on a redirect parameter would expire immediately.
WordPress.Security.EscapeOutput.OutputNotEscaped on $this-&gt;render_poll_markup(&#8230;) / poll_js_tag() (class-lh-polls-embed.php)
Both methods build their return values entirely from esc_html(), esc_attr(), esc_url(), esc_textarea(), wp_nonce_field(), and wp_json_encode() with JSON_HEX_TAG/JSON_HEX_AMP — every dynamic value is escaped at the point of output within those methods. PCP cannot trace escaping through a method&#8217;s internal implementation.
WordPress.WP.EnqueuedResources.NonEnqueuedStylesheet / NonEnqueuedScript (class-lh-polls-embed.php, serve_poll_document)
The embed view (is_embed()) is a complete self-contained HTML document output directly via template_redirect + exit — it never calls wp_head()/wp_footer(), so wp_enqueue_style()/wp_enqueue_script() would never print. This is the intentional zero-theme-dependency design for the embed view. The standalone singular view (filter_the_content) does use wp_enqueue_style() correctly.
WordPress.Security.ValidatedSanitizedInput.InputNotSanitized on $_GET[&#8216;redirect&#8217;]
Passed through esc_url_raw( urldecode( wp_unslash( $_GET[&#8216;redirect&#8217;] ) ) ). PCP cannot trace sanitisation through urldecode().
WordPress.Security.NonceVerification in LH_Polls_Voting::handle_form_post / process_vote / process_change_vote
The nonce (lh_poll_nonce) is verified once at the top of handle_form_post() via wp_verify_nonce() before any $_POST data is processed. process_vote() and process_change_vote() are private methods called only after this check succeeds; PCP flags each method independently and cannot trace the call chain.
""" ;
  sioc:topic <https://lhero.org/lh_portfolio-type/doc-section/>, <https://lhero.org/?taxonomy=author&term=cap-1> .

<https://lhero.org/author/1/#account> rdfs:seeAlso <https://lhero.org/author/1/?feed=lhrdf&format=turtle> .
<https://lhero.org/lh_portfolio-type/doc-section/> rdfs:seeAlso <https://lhero.org/lh_portfolio-type/doc-section/?feed=lhrdf&format=turtle> .
<https://lhero.org/?taxonomy=author&term=cap-1> rdfs:seeAlso <https://lhero.org/?taxonomy=author&term=cap-1&feed=lhrdf&format=turtle> .
