Skip to content

Veo#979

Draft
polina-c wants to merge 14 commits into
flutter:mainfrom
polina-c:veo
Draft

Veo#979
polina-c wants to merge 14 commits into
flutter:mainfrom
polina-c:veo

Conversation

@polina-c

Copy link
Copy Markdown
Collaborator

/Users/polina/_/genui/tool/e2e/test/veo_chat/generate_video_test/generated_video_2026-06-22T00-49-58.475478.mp4

@github-actions

Copy link
Copy Markdown

Package publishing

Package Version Status Publish tag (post-merge)
package:a2ui_core 0.0.1-wip002 ready to publish a2ui_core-v0.0.1-wip002
package:genai_primitives 0.2.4 ready to publish genai_primitives-v0.2.4
package:genui 0.9.2 already published at pub.dev
package:genui_a2a 0.9.0 already published at pub.dev
package:json_schema_builder 0.1.5 already published at pub.dev

Documentation at https://github.com/dart-lang/ecosystem/wiki/Publishing-automation.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a new example application, veo_chat, which demonstrates video generation using the Gemini Veo API. It includes platform-specific configurations for Android, iOS, macOS, Linux, Windows, and Web, along with integration tests, smoke tests, and a fake AI client for testing. The code review feedback highlights a critical syntax error in ai_client.dart regarding map initialization, a high-severity security vulnerability where the sensitive Google AI API key could be leaked to untrusted external URIs during video downloads, and numerous copy-paste errors across configuration files, package names, app titles, manifests, and build scripts where references to simple_chat were not updated to veo_chat.

Comment on lines +113 to +116
final parameters = <String, dynamic>{
'aspectRatio': ?aspectRatio,
'negativePrompt': ?negativePrompt,
};

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

The syntax used for adding optional parameters to the parameters map is incorrect. The ? prefix is not valid Dart syntax for this purpose. You should use collection-if to conditionally add the entries to the map.

Suggested change
final parameters = <String, dynamic>{
'aspectRatio': ?aspectRatio,
'negativePrompt': ?negativePrompt,
};
final parameters = <String, dynamic>{
if (aspectRatio != null) 'aspectRatio': aspectRatio,
if (negativePrompt != null) 'negativePrompt': negativePrompt,
};

Comment on lines +198 to +202
Future<Uint8List> _downloadVideo(Uri uri) async {
final http.Response response = await http.get(
uri,
headers: {'x-goog-api-key': _apiKey},
);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-high high

The _downloadVideo method downloads a generated video from a URI returned by the Gemini Veo API. However, it makes an HTTP GET request to the parsed uri and includes the sensitive x-goog-api-key header containing the user's Google AI API key (_apiKey) without validating that the URI's host belongs to a trusted Google domain.

If an attacker can manipulate the API response (e.g., via prompt injection or response spoofing) to return an arbitrary external URI, the application will perform a request to the attacker's server and leak the sensitive Google AI API key in the x-goog-api-key header.

Remediation

Validate that the URI's scheme is https and its host belongs to a trusted Google domain (e.g., *.googleapis.com or *.googleusercontent.com) before making the request. Additionally, only include the x-goog-api-key header if the host is trusted.

  Future<Uint8List> _downloadVideo(Uri uri) async {
    final bool isTrustedHost = uri.scheme == 'https' && (uri.host.endsWith('.googleapis.com') || uri.host.endsWith('.googleusercontent.com'));
    if (!isTrustedHost) {
      throw StateError('Untrusted video download URI: $uri');
    }
    final http.Response response = await http.get(
      uri,
      headers: {'x-goog-api-key': _apiKey},
    );


# The name of the executable created for the application. Change this to change
# the on-disk name of your application.
set(BINARY_NAME "simple_chat")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The BINARY_NAME and APPLICATION_ID (line 10) are set to simple_chat. They should be updated for the veo_chat example.

set(BINARY_NAME "veo_chat")

if (use_header_bar) {
GtkHeaderBar* header_bar = GTK_HEADER_BAR(gtk_header_bar_new());
gtk_widget_show(GTK_WIDGET(header_bar));
gtk_header_bar_set_title(header_bar, "simple_chat");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The window title is hardcoded as simple_chat. It should be updated to veo_chat. This also applies to line 57.

    gtk_header_bar_set_title(header_bar, "veo_chat");


Renders canned A2UI samples through `ChatScreen` with a `FakeAiClient` — no API key.

From `examples/simple_chat`:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The path in the instruction seems to be incorrect. It should point to examples/veo_chat.

Suggested change
From `examples/simple_chat`:
From `examples/veo_chat`:

<!-- iOS meta tags & icons -->
<meta name="mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
<meta name="apple-mobile-web-app-title" content="simple_chat" />

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The web app title is set to simple_chat. It should be updated to veo_chat. This also applies to the <title> tag on line 35.

    <meta name="apple-mobile-web-app-title" content="veo_chat" />

Comment on lines +2 to +3
"name": "simple_chat",
"short_name": "simple_chat",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The name and short_name in the web manifest should be updated from simple_chat to veo_chat.

Suggested change
"name": "simple_chat",
"short_name": "simple_chat",
"name": "veo_chat",
"short_name": "veo_chat",

@@ -0,0 +1,108 @@
# Project-level configuration.
cmake_minimum_required(VERSION 3.14)
project(simple_chat LANGUAGES CXX)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The project name and binary name (line 7) are set to simple_chat. They should be updated to veo_chat.

project(veo_chat LANGUAGES CXX)

BLOCK "040904e4"
BEGIN
VALUE "CompanyName", "com.example" "\0"
VALUE "FileDescription", "simple_chat" "\0"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The resource file contains several values from simple_chat that should be updated to veo_chat (e.g., FileDescription, InternalName, OriginalFilename, ProductName).

            VALUE "FileDescription", "veo_chat" "\0"

FlutterWindow window(project);
Win32Window::Point origin(10, 10);
Win32Window::Size size(1280, 720);
if (!window.Create(L"simple_chat", origin, size)) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The window title is hardcoded as simple_chat. It should be updated to veo_chat.

  if (!window.Create(L"veo_chat", origin, size)) {

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant