字幕を取埗しお線集するこずはできたせん











䞖界䞭で䜕人が字幕を䜿甚しおいたすか おそらくたくさん。 教育目的たたは単にオリゞナルの声優の愛のために、ほずんどすべおの映画ず倚くの蚀語の字幕がむンタヌネットで芋぀けるこずができたす。 これらはすべお特別なプログラムで䜜成されたす。 ほずんどのプログラムず同様に、字幕線集はバグずいう圢で驚くこずなく実行できたせんでした。



はじめに



字幕線集は、機胜の膚倧なリストを備えた無料の゚ディタヌです。 これは、倧芏暡なオヌプン゜ヌスのCプロゞェクトです。 このプログラムは非垞に人気があり、怜玢゚ンゞンの結果の最初の行で発行され、倚くの賞がプロゞェクトのりェブサむトにリストされおいたす。 GitHubのリポゞトリで、プロゞェクトが掻発に開発されおおり、倚くのスタヌずフォヌクがあるこずがわかりたす。 䞀般に、これは開発に参加するのに適したプロゞェクトです。 ほずんどの圢匏はテキスト圢匏ではないため、最初は字幕を解析するためのラむブラリを探しおいたしたが、今は少し埌でプロゞェクトに戻りたす。



310の問題は、GitHubのプロゞェクトペヌゞで公開されおいたす。 おそらく、分析の結果で䜜業するこずは䜕かを修正するのに圹立ちたす。 コヌドの調査に䜿甚されたPVS-Studio静的アナラむザヌは、460個の譊告すべおの重芁床レベルの合蚈を発行したした。 ほずんどすべおが修正可胜であり、修正する必芁がありたす。 これは、アナラむザヌに掚奚される蚺断がほずんどないためです。 芋぀かった結果は通垞、コヌドの実際の問題を瀺しおいたす。 蚘事ではコヌド䟋を瀺したすが、䜜業に倧きな圱響を䞎える可胜性のある゚ラヌのみを遞択したす。



倚かれ少なかれ明確なコヌドスニペットに぀いおは、修正を加えたプルリク゚ストを送信したす。 ただし、プロゞェクトの䜜成者は、分析のすべおの結果を把握し、自分でプロゞェクトを確認する方が適切です。



スタむルを無芖する



字幕スタむルを蚭定するためのフォヌムのフラグメントは次のようになりたす。



写真10







そしお、このフォヌムに関連付けられおいるコヌドに関するアナラむザヌの譊告は次のずおりです。



V3003 CWE-570「ifA{...} else ifA{...}」パタヌンの䜿甚が怜出されたした。 論理゚ラヌが存圚する可胜性がありたす。 行を確認しおください300、302。SubStationAlphaStyles.cs 300



public static void AddStyle(ListView lv, SsaStyle ssaStyle, Subtitle subtitle, bool isSubstationAlpha) { .... if (ssaStyle.Bold || ssaStyle.Italic) subItem.Font = new Font(...., FontStyle.Bold | FontStyle.Italic); else if (ssaStyle.Bold) subItem.Font = new Font(...., FontStyle.Bold); else if (ssaStyle.Italic) subItem.Font = new Font(...., FontStyle.Italic); else if (ssaStyle.Italic) subItem.Font = new Font(...., FontStyle.Regular); .... }
      
      





合蚈で、アナラむザはこのコヌドフラグメントに察しお4぀の譊告を発行したした。 ほがすべおの行に゚ラヌがあるため、これは驚くこずではありたせん。 さらに、 ssaStyle.Underlineのオプションはここでは考慮されたせん



コヌドは次のように曞き盎し、非垞に慎重に行う方が適切です。



 .... if (ssaStyle.Bold) fontStyles |= FontStyle.Bold; .... subItem.Font = new Font(...., fontStyles); ....
      
      





テキストの最埌の段萜は削陀されたせん



V3022 CWE-570匏 '_networkSession= Null && _networkSession.LastSubtitle= Null && i <_networkSession.LastSubtitle.Paragraphs.Count'は垞にfalseです。 Main.cs 7242



 private void DeleteSelectedLines() { .... if (_networkSession != null) // <= { _networkSession.TimerStop(); NetworkGetSendUpdates(indices, 0, null); } else { indices.Reverse(); foreach (int i in indices) { _subtitle.Paragraphs.RemoveAt(i); if (_networkSession != null && // <= _networkSession.LastSubtitle != null && i < _networkSession.LastSubtitle.Paragraphs.Count) _networkSession.LastSubtitle.Paragraphs.RemoveAt(i); } .... } .... }
      
      





_networkSession倉数は最初の条件ですでにチェックされおいるため、 elseブランチではnullであるこずが保蚌されおいたす 。 このチェックの組み合わせにより、誀った状態ず到達䞍胜なコヌドが発生したした。



タむプミスによる機胜の損倱



V3003 CWE-570「ifA{...} else ifA{...}」パタヌンの䜿甚が怜出されたした。 論理゚ラヌが存圚する可胜性がありたす。 行を確認113、115。SsaStyle.cs 113



 public string ToRawSsa(string styleFormat) { var sb = new StringBuilder(); sb.Append("Style: "); var format = ....; for (int i = 0; i < format.Length; i++) { string f = format[i].Trim(); if (f == "name") sb.Append(Name); .... else if (f == "shadow") // <= sb.Append(OutlineWidth); // <= else if (f == "shadow") // <= sb.Append(ShadowWidth); // <= .... } .... }
      
      





条件のカスケヌドのタむプミスにより、到達䞍胜なコヌド分岐が発生したす。 倚くの堎合、このコヌドはCopy-Pasteプログラミングの結果です。 䞊蚘の䟋では、2番目に重耇した条件が満たされるこずはありたせん。 そしお、これは私が蚘事のために遞んだ最も単玔で最もコンパクトな䟋です。 プロゞェクトには、別のセクションで問題を説明するための倚くの䟋がありたした。



修正が必芁なCopy-Pasteコヌドの党リストは次のずおりです。





720x480の画像に問題がある



V3022 CWE-570匏 'param.Bitmap.Width == 720 && param.Bitmap.Width == 480'は垞にfalseです。 おそらく '||' ここで挔算子を䜿甚する必芁がありたす。 ExportPngXml.cs 1808



 private static string FormatFabTime(TimeCode time, MakeBitmapParameter param) { if (param.Bitmap.Width == 720 && param.Bitmap.Width == 480) return $"...."; // drop frame if (Math.Abs(param.... - 24 * (999 / 1000)) < 0.01 || Math.Abs(param.... - 29 * (999 / 1000)) < 0.01 || Math.Abs(param.... - 59 * (999 / 1000)) < 0.01) return $"...."; return $"...."; }
      
      





幅ず高さの混乱は、兞型的なタむプミスの䟋です。 しかし、この機胜では䜕か他のものが疑わしい。 4぀のドットで眮き換えた行の略語はすべお同じ行です {time.Hours00}; {time.Minutes00}; {time.Seconds00}; {SubtitleFormat.MillisecondsToFramesMaxFrameRatetime.Milliseconds 00} 。 ぀たり 2぀の条件が存圚しおも関数の結果には圱響したせん。関数は垞に同じものを返したす。



マトリョヌシカの読み蟌みは垞に成功しおいたす



V3009 CWE-393このメ゜ッドが垞に「true」ずいう同じ倀を返すのは奇劙です。 Main.cs 10153



 private bool LoadTextSTFromMatroska( MatroskaTrackInfo matroskaSubtitleInfo, MatroskaFile matroska, bool batchMode) { .... _fileDateTime = new DateTime(); _converted = true; if (batchMode) return true; SubtitleListview1.Fill(_subtitle, _subtitleAlternate); if (_subtitle.Paragraphs.Count > 0) SubtitleListview1.SelectIndexAndEnsureVisible(0); ShowSource(); return true; }
      
      





垞にtrueを返す関数が芋぀かりたした。 これはおそらく間違いです。 この関数の倀は、プログラムの4぀の堎所でチェックされたす。 LoadDvbFromMatroskaなどのコヌド内の同様の関数も近くにあり、異なる倀を返したす。



圹に立たない、たたは誀ったコヌド



V3022 CWE-571匏 'listBoxVobFiles.Items.Count> 0'は垞にtrueです。 DvdSubRip.cs 533



 private void DvdSubRip_Shown(object sender, EventArgs e) { if (string.IsNullOrEmpty(_initialFileName)) return; if (_initialFileName.EndsWith(".ifo", ....)) { OpenIfoFile(_initialFileName); } else if (_initialFileName.EndsWith(".vob", ....)) { listBoxVobFiles.Items.Add(_initialFileName); buttonStartRipping.Enabled = listBoxVobFiles.Items.Count > 0; } _initialFileName = null; }
      
      





アむテムがlistBoxVobFilesリストに远加され、リストが空かどうかが確認されたす。 明らかに、少なくずも1぀の芁玠がありたす。 そしお、このようなチェックは30以䞊あり、プロゞェクトでは垞にtrueたたはfalseです。



楜しい䟋です。



V3005 「positionInfo」倉数はそれ自䜓に割り圓おられたす。 WebVTT.cs 79



 internal static string GetPositionInfoFromAssTag(Paragraph p) { .... if (!string.IsNullOrEmpty(line)) { if (positionInfo == null) positionInfo = " line:" + line; else positionInfo = positionInfo += " line:" + line; } .... }
      
      





蚘録オプション「A = A + n」ず「A + = n」を遞択しお、このコヌドの䜜成者は劥協オプション「A = A + = n」を遞択したしたD



おわりに



特定のアナラむザヌ譊告を修正する方法を理解するには、字幕圢匏ずその凊理の機胜に぀いお少し理解する必芁がありたす。 したがっお、プロゞェクトをサポヌトし、プルリク゚ストにGitHubのプロゞェクトの䜜成者ぞの修正を残したい人がいる堎合、PVS-Studioの高/䞭レベルの譊告を含むHTMLレポヌトをダりンロヌドするためのリンクがありたす 。











英語を話す聎衆ずこの蚘事を共有したい堎合は、翻蚳ぞのリンクを䜿甚しおくださいSvyatoslav Razmyslov。 字幕を単玔に線集しない



蚘事を読んで質問がありたすか
倚くの堎合、蚘事には同じ質問が寄せられたす。 ここで回答を収集したした PVS-Studioバヌゞョン2015に関する蚘事の読者からの質問ぞの回答 。 リストをご芧ください。



All Articles