在Mac UTF-8上比较具有特殊字符的路径

时间:2016-11-07 15:26:25

标签: c macos utf-8 kernel-extension

我们有一个kext,用于检查路径是否是另一个路径的子目录,如果是,则会产生一些魔法。

只要我们的路径中没有特殊字符(等字符)

,这一切都可以正常工作

我们通过可以与kext通信的帮助应用程序将一些工作路径提供给系统。

我已将问题与此代码隔离开来:

#include <stdio.h>
#include <string.h>

int main ()
{
  char* path = "/Users/user/test/tëst/test"; //Sent by the system
  char* wp = "/Users/user/test/tëst"; //Some path we claim to be ours

  size_t wp_len = strlen(wp);

  if (strncmp (wp,path,wp_len) == 0) //Check is path is a subpath
  {
    printf ("matched %s\n", path);
  }else {
    printf ("could not match\n");

  }
  return 0;
}

我已经创建了一个Gist,因此浏览器不会丢失编码:https://gist.github.com/fvandepitte/ec28f4321a48061808d0095853af7bd7

有人知道如何检查pathwp的子路径而不会失去太多性能(此代码在内核中运行)?

1 个答案:

答案 0 :(得分:1)

我将源直接从浏览器复制/粘贴到文件(test.c)中。它为我打印could not match

如果我使用od转储文件,这就是我所看到的:

bash-3.2$ od -c test.c                                                     
0000000    #   i   n   c   l   u   d   e       <   s   t   d   i   o   .   
0000020    h   >  \n   #   i   n   c   l   u   d   e       <   s   t   r   
0000040    i   n   g   .   h   >  \n  \n   i   n   t       m   a   i   n   
0000060        (   )  \n   {  \n           c   h   a   r   *       p   a   
0000100    t   h       =       "   /   U   s   e   r   s   /   u   s   e   
0000120    r   /   t   e   s   t   /   t   ë  **   s   t   /   t   e   s   
0000140    t   "   ;       /   /   S   e   n   t       b   y       t   h   
0000160    e       s   y   s   t   e   m  \n           c   h   a   r   *   
0000200        w   p       =               "   /   U   s   e   r   s   /   
0000220    u   s   e   r   /   t   e   s   t   /   t   e    ̈  **   s   t   
0000240    "   ;       /   /   S   o   m   e       p   a   t   h       w   

请注意,path的tëst出现为t ë ** s t, 但是wp的t t e ̈ ** s t出现为strncmp,这是不同的:所以ëepath进行比较时会失败。

如果我将wp中的tëst复制到matched /Users/user/test/tëst/test的分配中,那么我会strncmp,因此strncmp似乎工作正常。

我不知道这两个字符串是不同的,我只能假设这两个字符串以某种方式使用不同的编码。 ë函数比较每个字节的字符串,因此e ̈strncmp被视为不同。如果你想使用od -c pathtest.cpp,那么不幸的是除了确保两个字符串使用相同的编码之外,没有其他简单的解决方案。

FWIW - 我在macOS 10.12.1上运行,使用clang版Apple LLVM 8.0.0版(clang-800.0.42.1)

编辑:我从你的github链接下载了pathtest.cpp,只是为了仔细检查。我已经运行了import java.io.*; import java.util.Scanner; public class CreateFile { public static void main(String[] args) throws IOException { Scanner input = new Scanner(System.in); FileWriter fwriter = new FileWriter("c:\\Students.dat"); PrintWriter StudentFile = new PrintWriter(fwriter); String name = " "; String next = " "; int age = 0; int hm = 0; double gpa = 0.0; System.out.print("How many student records would you like to enter: "); hm = input.nextInt(); for (int x = 1; x <= hm; x++) { System.out.print("Enter Name: "); name = input.nextLine(); input.nextLine(); System.out.print("Enter Age: "); age = input.nextInt(); System.out.print("Enter GPA: "); gpa = input.nextDouble(); next = input.nextLine(); StudentFile.println(name); StudentFile.println(age); StudentFile.println(gpa); } StudentFile.close(); System.exit(0); } } ,我看到了同样的问题。