From 3b513827977ff28be9ff59ecfdf1fef35286b9e3 Mon Sep 17 00:00:00 2001 From: Matt Batchelder Date: Sat, 21 Feb 2026 20:08:18 -0500 Subject: [PATCH] Enhance Gitea support by improving base64 decoding and UTF-8 encoding handling --- dist/oribi-tech-sync.zip | Bin 44396 -> 44659 bytes includes/api-client.php | 8 +++++--- includes/post-sync.php | 17 +++++++++-------- includes/push-client.php | 15 +++++++++++++-- 4 files changed, 27 insertions(+), 13 deletions(-) diff --git a/dist/oribi-tech-sync.zip b/dist/oribi-tech-sync.zip index d11c66ab894fd07b36d22883065cbd7a2241899b..e53d98b0c3c993ef13c5986e5137f8d19958c563 100644 GIT binary patch delta 10616 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 diff --git a/includes/api-client.php b/includes/api-client.php index ff3c009..006ad15 100644 --- a/includes/api-client.php +++ b/includes/api-client.php @@ -380,13 +380,15 @@ function oribi_sync_fetch_file( string $api_base, string $branch, string $file_p $body = wp_remote_retrieve_body( $response ); - // For Gitea, the /contents/ endpoint returns base64-encoded content in JSON + // For Gitea, the /contents/ endpoint returns base64-encoded content in JSON. + // Gitea (like GitHub) inserts \n every 60 chars in the base64 — strip them before decoding. if ( $provider === 'gitea' ) { $decoded = json_decode( $body, true ); if ( isset( $decoded['content'] ) && is_string( $decoded['content'] ) ) { - $body = base64_decode( $decoded['content'], true ); + $clean = str_replace( [ "\r", "\n", " " ], '', $decoded['content'] ); + $body = base64_decode( $clean, true ); if ( $body === false ) { - return new WP_Error( 'oribi_sync_decode_error', 'Failed to decode base64 content from Gitea' ); + return new WP_Error( 'oribi_sync_decode_error', 'Failed to decode base64 content from Gitea.' ); } } } diff --git a/includes/post-sync.php b/includes/post-sync.php index 186b938..3ae727b 100644 --- a/includes/post-sync.php +++ b/includes/post-sync.php @@ -858,8 +858,9 @@ function oribi_sync_trash_removed_posts( array $current_slugs ): array { function oribi_sync_generate_post_markdown( WP_Post $post ): string { $fm = "---\n"; - // Title (escape newlines) - $fm .= 'title: ' . str_replace( [ "\r", "\n" ], ' ', $post->post_title ) . "\n"; + // Title — decode HTML entities (WP stores & etc. in DB) so the YAML + // file contains the literal character. On pull-back WP re-encodes correctly. + $fm .= 'title: ' . str_replace( [ "\r", "\n" ], ' ', html_entity_decode( $post->post_title, ENT_QUOTES | ENT_HTML5, 'UTF-8' ) ) . "\n"; $fm .= 'slug: ' . $post->post_name . "\n"; $fm .= 'status: ' . $post->post_status . "\n"; @@ -874,27 +875,27 @@ function oribi_sync_generate_post_markdown( WP_Post $post ): string { $fm .= 'author: ' . $author->user_login . "\n"; } - // Categories + // Categories — decode HTML entities stored by WP $cats = get_the_category( $post->ID ); if ( ! empty( $cats ) ) { $fm .= "categories:\n"; foreach ( $cats as $cat ) { - $fm .= ' - ' . $cat->name . "\n"; + $fm .= ' - ' . html_entity_decode( $cat->name, ENT_QUOTES | ENT_HTML5, 'UTF-8' ) . "\n"; } } - // Tags + // Tags — decode HTML entities stored by WP $post_tags = get_the_tags( $post->ID ); if ( ! empty( $post_tags ) ) { $fm .= "tags:\n"; foreach ( $post_tags as $tag ) { - $fm .= ' - ' . $tag->name . "\n"; + $fm .= ' - ' . html_entity_decode( $tag->name, ENT_QUOTES | ENT_HTML5, 'UTF-8' ) . "\n"; } } - // Excerpt + // Excerpt — decode HTML entities stored by WP if ( ! empty( $post->post_excerpt ) ) { - $fm .= 'excerpt: ' . str_replace( [ "\r", "\n" ], ' ', $post->post_excerpt ) . "\n"; + $fm .= 'excerpt: ' . str_replace( [ "\r", "\n" ], ' ', html_entity_decode( $post->post_excerpt, ENT_QUOTES | ENT_HTML5, 'UTF-8' ) ) . "\n"; } // Featured image (absolute URL so it round-trips cleanly) diff --git a/includes/push-client.php b/includes/push-client.php index fc644a1..6b65d8f 100644 --- a/includes/push-client.php +++ b/includes/push-client.php @@ -104,7 +104,7 @@ function oribi_sync_api_request( string $method, string $url, array $body, strin 'method' => $method, 'timeout' => 30, 'headers' => $headers, - 'body' => wp_json_encode( $body, JSON_UNESCAPED_UNICODE ), + 'body' => wp_json_encode( $body, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES ), ]; $response = wp_remote_request( $url, $args ); @@ -152,9 +152,15 @@ function oribi_sync_gitea_get_file_meta( string $api_base, string $branch, strin return $result; } + // Gitea inserts \n every 60 chars in base64 — strip before decoding. + $raw_b64 = $result['content'] ?? ''; + $content = ! empty( $raw_b64 ) + ? base64_decode( str_replace( [ "\r", "\n", " " ], '', $raw_b64 ), true ) + : ''; + return [ 'sha' => $result['sha'] ?? '', - 'content' => isset( $result['content'] ) ? base64_decode( $result['content'] ) : '', + 'content' => ( $content !== false ) ? $content : '', ]; } @@ -182,6 +188,11 @@ function oribi_sync_gitea_put_file( ?string $sha = null, string $message = '' ) { + // Validate and fix UTF-8 encoding before base64-encoding + if ( ! mb_check_encoding( $content, 'UTF-8' ) ) { + $content = mb_convert_encoding( $content, 'UTF-8', 'UTF-8, ISO-8859-1, Windows-1252' ); + } + $encoded_path = implode( '/', array_map( 'rawurlencode', explode( '/', $filepath ) ) ); $url = $api_base . '/contents/' . $encoded_path;